|
| 1 | + |
| 2 | +import modulo |
| 3 | +import time |
| 4 | +import math |
| 5 | + |
| 6 | +lastUpdateTime = time.time() |
| 7 | + |
| 8 | + |
| 9 | +class Pong : |
| 10 | + |
| 11 | + def __init__(self) : |
| 12 | + self._port = modulo.Port() |
| 13 | + self._display = modulo.Display(self._port) |
| 14 | + self._knob = modulo.Knob(self._port) |
| 15 | + |
| 16 | + self._width = self._display.get_width() |
| 17 | + self._height = self._display.get_height() |
| 18 | + self._paddleWidth = 3 |
| 19 | + self._paddleHeight = 10 |
| 20 | + self._leftPaddleSpeed = 30 |
| 21 | + |
| 22 | + self._leftPaddlePos = self._height/2 |
| 23 | + self._rightPaddlePos = self._height/2 |
| 24 | + self._knobPos = self._knob.get_position() |
| 25 | + |
| 26 | + self._paused = True |
| 27 | + self._lastUpdateTime = time.time() |
| 28 | + self._ballX = 10 |
| 29 | + self._ballY = self._height/2 |
| 30 | + |
| 31 | + self._ballSpeed = 30 |
| 32 | + self._ballDx = .9 |
| 33 | + self._ballDy = .1 |
| 34 | + |
| 35 | + self._rightScore = 0 |
| 36 | + self._leftScore = 0 |
| 37 | + |
| 38 | + def update_input(self) : |
| 39 | + newKnobPos = self._knob.get_position() |
| 40 | + self._rightPaddlePos += 5*(newKnobPos - self._knobPos) |
| 41 | + self._knobPos = newKnobPos |
| 42 | + |
| 43 | + minPaddlePosition = self._paddleHeight/2 |
| 44 | + maxPaddlePosition = self._height-self._paddleHeight/2 |
| 45 | + |
| 46 | + self._rightPaddlePos = max(self._rightPaddlePos, minPaddlePosition) |
| 47 | + self._rightPaddlePos = min(self._rightPaddlePos, maxPaddlePosition) |
| 48 | + |
| 49 | + def end_round(self) : |
| 50 | + self.draw() |
| 51 | + |
| 52 | + # Wait for 3 seconds |
| 53 | + pauseStartTime = time.time() |
| 54 | + while time.time() < pauseStartTime+3 : |
| 55 | + self._knob.set_hsv(time.time()-pauseStartTime, 1, 1) |
| 56 | + self._knob.set_color(0,0,0) |
| 57 | + |
| 58 | + # Move the ball back to the center |
| 59 | + self._ballX = self._display.get_width()/2 |
| 60 | + self._ballY = self._display.get_height()/2 |
| 61 | + |
| 62 | + # Reset the last update time, since we want to start the game from now |
| 63 | + self._lastUpdateTime = time.time() |
| 64 | + |
| 65 | + def check_right_goal(self) : |
| 66 | + rightGoal = self._display.get_width()-self._paddleWidth |
| 67 | + |
| 68 | + if (self._ballX < rightGoal) : |
| 69 | + return False |
| 70 | + |
| 71 | + posOnPaddle = self._ballY-self._rightPaddlePos |
| 72 | + |
| 73 | + # Check and see if the ball missed the paddle |
| 74 | + if abs(posOnPaddle) > .6*self._paddleHeight : |
| 75 | + return True |
| 76 | + |
| 77 | + angle = .5*math.pi*posOnPaddle/self._paddleHeight |
| 78 | + self._ballDx = -math.cos(angle) |
| 79 | + self._ballDy = math.sin(angle) |
| 80 | + return False |
| 81 | + |
| 82 | + def check_left_goal(self) : |
| 83 | + leftGoal = self._paddleWidth |
| 84 | + |
| 85 | + if (self._ballX > leftGoal) : |
| 86 | + return False |
| 87 | + |
| 88 | + posOnPaddle = self._ballY-self._leftPaddlePos |
| 89 | + |
| 90 | + # Check and see if the ball missed the paddle |
| 91 | + if abs(posOnPaddle) > .6*self._paddleHeight : |
| 92 | + return True |
| 93 | + |
| 94 | + angle = .5*math.pi*posOnPaddle/self._paddleHeight |
| 95 | + self._ballDx = -math.cos(angle) |
| 96 | + self._ballDy = math.sin(angle) |
| 97 | + return False |
| 98 | + |
| 99 | + |
| 100 | + def update_game(self) : |
| 101 | + if self._paused : |
| 102 | + return False |
| 103 | + |
| 104 | + leftGoal = self._paddleWidth |
| 105 | + |
| 106 | + if self.check_right_goal() : |
| 107 | + self._leftScore += 1 |
| 108 | + self.end_round() |
| 109 | + return |
| 110 | + |
| 111 | + if self.check_left_goal() : |
| 112 | + self._rightScore += 1 |
| 113 | + self.end_round() |
| 114 | + return |
| 115 | + |
| 116 | + currentTime = time.time() |
| 117 | + dt = currentTime-self._lastUpdateTime |
| 118 | + self._lastUpdateTime = time.time() |
| 119 | + |
| 120 | + if (self._leftPaddlePos > self._ballY+5) : |
| 121 | + self._leftPaddlePos -= dt*self._leftPaddleSpeed |
| 122 | + if (self._leftPaddlePos < self._ballY-5) : |
| 123 | + self._leftPaddlePos += dt*self._leftPaddleSpeed |
| 124 | + |
| 125 | + if (self._ballX <= leftGoal) : |
| 126 | + self._ballDx = -self._ballDx |
| 127 | + |
| 128 | + if (self._ballY >= self._height-1 or |
| 129 | + self._ballY <= 0) : |
| 130 | + self._ballDy = -self._ballDy |
| 131 | + |
| 132 | + self._ballX += self._ballSpeed*self._ballDx*dt |
| 133 | + self._ballY += self._ballSpeed*self._ballDy*dt |
| 134 | + |
| 135 | + def draw(self) : |
| 136 | + self._display.clear() |
| 137 | + |
| 138 | + self._display.draw_ellipse(self._ballX, self._ballY, 2, 2, 1) |
| 139 | + |
| 140 | + self._display.draw_rectangle(self._width-self._paddleWidth, |
| 141 | + self._rightPaddlePos-self._paddleHeight/2, self._paddleWidth, |
| 142 | + self._paddleHeight, |
| 143 | + fill=1); |
| 144 | + |
| 145 | + self._display.draw_rectangle(0, |
| 146 | + self._leftPaddlePos-self._paddleHeight/2, self._paddleWidth, |
| 147 | + self._paddleHeight, |
| 148 | + fill=1); |
| 149 | + |
| 150 | + self._display.set_cursor(self._width/3, 0) |
| 151 | + self._display.write(self._leftScore) |
| 152 | + |
| 153 | + self._display.set_cursor(self._width*2/3, 0) |
| 154 | + self._display.write(self._rightScore) |
| 155 | + |
| 156 | + if self._paused : |
| 157 | + self._display.draw_rectangle(25, 10, |
| 158 | + self._width-40, self._height-20, fill=0, outline=1) |
| 159 | + self._display.set_cursor(0, 15) |
| 160 | + self._display.writeln(" Paused.") |
| 161 | + self._display.writeln(" Press Knob") |
| 162 | + self._display.writeln(" to continue") |
| 163 | + |
| 164 | + |
| 165 | + self._display.update() |
| 166 | + |
| 167 | + def run(self) : |
| 168 | + knobWasPressed = False |
| 169 | + while True : |
| 170 | + knobIsPressed = self._knob.get_button() |
| 171 | + if knobIsPressed and not knobWasPressed : |
| 172 | + self._paused = not self._paused |
| 173 | + self._lastUpdateTime = time.time() |
| 174 | + knobWasPressed = knobIsPressed |
| 175 | + |
| 176 | + self.update_input() |
| 177 | + self.update_game() |
| 178 | + self.draw() |
| 179 | + |
| 180 | +pong = Pong() |
| 181 | +pong.run() |
| 182 | + |
0 commit comments