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 |