Stefan Schuermans commited on 2019-06-15 14:24:14
Showing 2 changed files, with 88 additions and 45 deletions.
... | ... |
@@ -126,74 +126,99 @@ void Pong::timeCall() |
126 | 126 |
planTimeCall(); |
127 | 127 |
} |
128 | 128 |
|
129 |
-/// computer player for left pad |
|
130 |
-void Pong::computerLeft() |
|
129 |
+/** |
|
130 |
+ * @brief computation of ideal pad position for computer players |
|
131 |
+ * @param[in] padBallX x coordinate of position of ball when hitting the pad |
|
132 |
+ * @param[in] padY current y coordinate of pad |
|
133 |
+ * @param[out] padYmin minimum ideal y position of pad |
|
134 |
+ * @param[out] padYmax maximum ideal y position of pad |
|
135 |
+ */ |
|
136 |
+void Pong::computerComputePadPos(int padBallX, int padY, |
|
137 |
+ int &padYmin, int &padYmax) const |
|
131 | 138 |
{ |
132 |
- // ball not moving towards pad: do not move |
|
133 |
- if (m_ballDirX >= 0) { |
|
139 |
+ // ball not moving towards pad |
|
140 |
+ if ((padBallX - m_ballPosX) * m_ballDirX <= 0) { |
|
141 |
+ // do not move if ball is still close to pad |
|
142 |
+ if (abs(padBallX - m_ballPosX) <= 2) { |
|
143 |
+ padYmin = padY; |
|
144 |
+ padYmax = padY; |
|
145 |
+ return; |
|
146 |
+ } |
|
147 |
+ // move pad to middle (might be 2 pixels wide) |
|
148 |
+ padYmin = (m_height - m_padSize) / 2; |
|
149 |
+ padYmax = (m_height - m_padSize + 1) / 2; |
|
134 | 150 |
return; |
135 | 151 |
} |
136 | 152 |
|
137 | 153 |
// compute expected ball position at pad |
138 |
- int expectedY = m_ballPosY + (m_ballPosX - 1) * m_ballDirY; |
|
139 |
- |
|
140 |
- // compute pad position to hit ball with center of pad |
|
141 |
- int padY = expectedY - m_padSize / 2; |
|
142 |
- |
|
143 |
- // do not move pad out of field |
|
144 |
- if (padY < 0) { |
|
145 |
- padY = 0; |
|
154 |
+ int ballPosX = m_ballPosX; // simulate were ball is going |
|
155 |
+ int ballPosY = m_ballPosY; |
|
156 |
+ int ballDirY = m_ballDirY; |
|
157 |
+ while ((padBallX - ballPosX) * m_ballDirX > 0) { // while moving to pad |
|
158 |
+ int deltaX = padBallX - ballPosX; |
|
159 |
+ int deltaY = deltaX * m_ballDirX * ballDirY; |
|
160 |
+ if (deltaY < -ballPosY) { |
|
161 |
+ deltaY = -ballPosY; |
|
162 |
+ ballPosX += deltaY * m_ballDirX * ballDirY; |
|
163 |
+ ballPosY = 0; |
|
164 |
+ ballDirY = 1; |
|
165 |
+ } |
|
166 |
+ else if (deltaY > m_height - 1 - ballPosY) { |
|
167 |
+ deltaY = m_height - 1 - ballPosY; |
|
168 |
+ ballPosX += deltaY * m_ballDirX * ballDirY; |
|
169 |
+ ballPosY = m_height - 1; |
|
170 |
+ ballDirY = -1; |
|
171 |
+ } else { |
|
172 |
+ ballPosX += deltaX; |
|
173 |
+ ballPosY += deltaY; |
|
146 | 174 |
} |
147 |
- if (padY > m_height - m_padSize) { |
|
148 |
- padY = m_height - m_padSize; |
|
149 | 175 |
} |
150 | 176 |
|
151 |
- // move pad |
|
152 |
- if (m_leftPosY < padY) { |
|
153 |
- ++m_leftPosY; |
|
154 |
- } |
|
155 |
- else if (m_leftPosY > padY) { |
|
156 |
- --m_leftPosY; |
|
157 |
- } |
|
177 |
+ // compute pad position to hit ball with center of pad |
|
178 |
+ padYmin = ballPosY - m_padSize / 2; |
|
179 |
+ padYmax = ballPosY - (m_padSize - 1) / 2; |
|
158 | 180 |
} |
159 | 181 |
|
160 |
-/// computer player for right pad |
|
161 |
-void Pong::computerRight() |
|
182 |
+/** |
|
183 |
+ * @brief move pad for computer players |
|
184 |
+ * @param[in] padYmin minimum desired y position of pad |
|
185 |
+ * @param[in] padYmax maximum desired y position of pad |
|
186 |
+ * @param[in,out] padPosY y position of pad |
|
187 |
+ */ |
|
188 |
+void Pong::computerMovePad(int padYmin, int padYmax, int &padPosY) const |
|
162 | 189 |
{ |
163 |
- // ball not moving towards pad: do not move |
|
164 |
- if (m_ballDirX <= 0) { |
|
165 |
- return; |
|
190 |
+ // move pad, do not move pad out of field |
|
191 |
+ if (padPosY > padYmax && padPosY > 0) { |
|
192 |
+ --padPosY; |
|
166 | 193 |
} |
167 |
- |
|
168 |
- // compute expected ball position at pad |
|
169 |
- int expectedY = m_ballPosY + (m_width - 2 - m_ballPosX) * m_ballDirY; |
|
170 |
- |
|
171 |
- // compute pad position to hit ball with center of pad |
|
172 |
- int padY = expectedY - m_padSize / 2; |
|
173 |
- |
|
174 |
- // do not move pad out of field |
|
175 |
- if (padY < 0) { |
|
176 |
- padY = 0; |
|
194 |
+ else if (padPosY < padYmin && padPosY < m_height - m_padSize) { |
|
195 |
+ ++padPosY; |
|
177 | 196 |
} |
178 |
- if (padY > m_height - m_padSize) { |
|
179 |
- padY = m_height - m_padSize; |
|
180 | 197 |
} |
181 | 198 |
|
182 |
- // move pad |
|
183 |
- if (m_rightPosY < padY) { |
|
184 |
- ++m_rightPosY; |
|
185 |
- } |
|
186 |
- else if (m_rightPosY > padY) { |
|
187 |
- --m_rightPosY; |
|
199 |
+/// computer player for left pad |
|
200 |
+void Pong::computerLeft() |
|
201 |
+{ |
|
202 |
+ int padYmin, padYmax; |
|
203 |
+ computerComputePadPos(1, m_leftPosY, padYmin, padYmax); |
|
204 |
+ computerMovePad(padYmin, padYmax, m_leftPosY); |
|
188 | 205 |
} |
206 |
+ |
|
207 |
+/// computer player for right pad |
|
208 |
+void Pong::computerRight() |
|
209 |
+{ |
|
210 |
+ int padYmin, padYmax; |
|
211 |
+ computerComputePadPos(m_width - 2, m_rightPosY, padYmin, padYmax); |
|
212 |
+ computerMovePad(padYmin, padYmax, m_rightPosY); |
|
189 | 213 |
} |
190 | 214 |
|
191 | 215 |
/// bounce ball |
192 | 216 |
void Pong::bounceBall() |
193 | 217 |
{ |
194 |
- bounceBallSide(); |
|
218 |
+ bounceBallSide(); // must be done before player bounce to be safe |
|
195 | 219 |
bounceBallLeft(); |
196 | 220 |
bounceBallRight(); |
221 |
+ bounceBallSide(); // must also be done after player bounce to be safe |
|
197 | 222 |
} |
198 | 223 |
|
199 | 224 |
/// bounce ball at sides |
... | ... |
@@ -61,6 +61,24 @@ protected: |
61 | 61 |
/// callback when requested time reached |
62 | 62 |
virtual void timeCall(); |
63 | 63 |
|
64 |
+ /** |
|
65 |
+ * @brief computation of ideal pad position for computer players |
|
66 |
+ * @param[in] padBallX x coordinate of position of ball when hitting the pad |
|
67 |
+ * @param[in] padY current y coordinate of pad |
|
68 |
+ * @param[out] padYmin minimum ideal y position of pad |
|
69 |
+ * @param[out] padYmax maximum ideal y position of pad |
|
70 |
+ */ |
|
71 |
+ void computerComputePadPos(int padBallX, int padY, |
|
72 |
+ int &padYmin, int &padYmax) const; |
|
73 |
+ |
|
74 |
+ /** |
|
75 |
+ * @brief move pad for computer players |
|
76 |
+ * @param[in] padYmin minimum desired y position of pad |
|
77 |
+ * @param[in] padYmax maximum desired y position of pad |
|
78 |
+ * @param[in,out] padPosY y position of pad |
|
79 |
+ */ |
|
80 |
+ void computerMovePad(int padYmin, int padYmax, int &padPosY) const; |
|
81 |
+ |
|
64 | 82 |
/// computer player for left pad |
65 | 83 |
void computerLeft(); |
66 | 84 |
|
67 | 85 |