PlatformIO package of the Teensy core framework compatible with GCC 10 & C++20
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

251 lines
6.1KB

  1. /*
  2. A Ping Pong game for 1 user, you can use the capacitive touch screen or a pot connected to A0
  3. If you have a buzzer connected to pin 8 you will have sound as well.
  4. */
  5. #include <SPI.h>
  6. #include <RA8875.h>
  7. #if defined(USE_FT5206_TOUCH)
  8. #include <Wire.h>
  9. #endif
  10. #define RA8875_CS 10
  11. #define RA8875_RESET 9
  12. #if defined(USE_FT5206_TOUCH)
  13. #define RA8875_INT 2
  14. #endif
  15. #define BEEPER_PIN 8
  16. uint8_t ballSize = 8;
  17. uint16_t ballColor = RA8875_YELLOW;
  18. uint8_t ballSpeed = 10; // lower numbers are faster
  19. uint8_t paddleH = 5;
  20. uint8_t paddleW = 30;
  21. int16_t paddleX = 20;
  22. int16_t paddleY = 0;
  23. int16_t oldPaddleY;
  24. int16_t scoreHumanTextX = 0;
  25. int16_t scoreCpuTextX = 0;
  26. int16_t ballTextX = 0;
  27. int16_t scoreTextY = 0;
  28. bool launchBall = true;
  29. int humanScore = 0;
  30. int cpuScore = 0;
  31. uint8_t maxBalls = 10;
  32. bool restart = true;
  33. #if defined(USE_FT5206_TOUCH)
  34. RA8875 tft = RA8875(RA8875_CS, RA8875_RESET, RA8875_INT);
  35. #else
  36. RA8875 tft = RA8875(RA8875_CS, RA8875_RESET);
  37. #endif
  38. int16_t ballDirX = 1;
  39. int16_t ballDirY = 1;
  40. int16_t ballX = 0;
  41. int16_t ballY = 0;
  42. int16_t oldBallX = -1;
  43. int16_t oldBallY = -1;
  44. uint16_t grey = tft.Color565(100, 100, 100);
  45. void setup() {
  46. tft.begin(RA8875_800x480);
  47. #if defined(USE_FT5206_TOUCH)
  48. tft.setTouchLimit(1);
  49. tft.armTouchISR(true);//touch screen interrupt it's armed
  50. #endif
  51. scoreTextY = tft.height() - (30 + 1 + (ballSize + 1)) + 15;
  52. }
  53. void loop() {
  54. if (restart) {
  55. restart = false;
  56. restartGame();
  57. }
  58. paddleRead();
  59. // update the ball's position and draw it on screen
  60. if (millis() % ballSpeed < 2) moveBall();
  61. }
  62. void moveBall() {
  63. bool started = false;
  64. if (launchBall) {
  65. launchBall = false;
  66. ballDirX = random(1, 5);
  67. ballDirY = random(1, 5);
  68. ballX = (tft.width() - 1) - (ballSize + ballDirY) ;
  69. ballY = (tft.height() / 2) + random(-30, 30);
  70. oldBallX = -1;
  71. oldBallY = -1;
  72. started = true;
  73. } else {
  74. bool reverseDirX = false;
  75. bool reverseDirY = false;
  76. if (ballX > tft.width() - (ballSize + 2)) reverseDirX = true;//RIGHT
  77. if (ballX < 0) {//missed ball!--------------------------------------
  78. tft.fillRect(oldBallX, oldBallY, ballSize, ballSize, RA8875_BLACK);
  79. tft.drawFastVLine(tft.width() - 1, 0, tft.height() - (30 + 1), grey);
  80. tone(BEEPER_PIN, 800, 100);
  81. launchBall = true;
  82. //delay(1000);
  83. maxBalls--;
  84. cpuScore += 100;
  85. setScore();
  86. if (maxBalls < 1) {
  87. tft.setCursor(CENTER, CENTER);
  88. tft.setFontScale(2);
  89. if (cpuScore > humanScore) {
  90. tft.print("YOU LOOSE!");
  91. } else if (cpuScore == humanScore) {
  92. tft.print("PARITY!");
  93. } else {
  94. tft.print("YOU WIN!");
  95. }
  96. setBallScore(0);
  97. setScore();
  98. delay(5000);
  99. tft.fillWindow();
  100. restart = true;
  101. return;
  102. } else {
  103. setBallScore(maxBalls);
  104. delay(1000);
  105. return;
  106. }
  107. }
  108. if (reverseDirX) {
  109. ballDirX = -ballDirX;
  110. beeper(false);
  111. }
  112. if ((ballY > tft.height() - (30 + 1 + (ballSize + 5)))) reverseDirY = true;//BOTTOM
  113. if (ballY < (ballSize)) reverseDirY = true;//TOP
  114. if (reverseDirY) {
  115. ballDirY = -ballDirY;
  116. beeper(false);
  117. }
  118. if (inPaddle(ballX, ballY, paddleX, paddleY, paddleH, paddleW)) {
  119. beeper(true);
  120. humanScore += 100;
  121. setScore();
  122. ballDirX = -ballDirX;
  123. ballDirY = -ballDirY;
  124. }
  125. ballX += ballDirX;
  126. ballY += ballDirY;
  127. }
  128. if (oldBallX != ballX || oldBallY != ballY) tft.fillRect(oldBallX, oldBallY, ballSize, ballSize, RA8875_BLACK);
  129. tft.fillRect(ballX, ballY, ballSize, ballSize, ballColor);
  130. if (started)tft.drawFastVLine(tft.width() - 1, 0, tft.height() - (30 + 1), grey);
  131. oldBallX = ballX;
  132. oldBallY = ballY;
  133. }
  134. void restartGame() {
  135. humanScore = 0;
  136. cpuScore = 0;
  137. maxBalls = 10;
  138. launchBall = true;
  139. //tft.clearScreen();
  140. tft.setFontScale(0);
  141. tft.setTextColor(RA8875_WHITE, RA8875_BLACK);
  142. tft.setCursor(30, scoreTextY);
  143. tft.print("Human: ");
  144. scoreHumanTextX = tft.getCursorX();
  145. tft.setCursor(120, scoreTextY);
  146. tft.print("CPU: ");
  147. scoreCpuTextX = tft.getCursorX();
  148. tft.setCursor(200, scoreTextY);
  149. tft.print("BALL: ");
  150. ballTextX = tft.getCursorX();
  151. tft.setCursor(tft.width() - 120, scoreTextY);
  152. tft.print("[ Damn Pong! ] ");
  153. tft.drawFastHLine(paddleX, tft.height() - (30 + 1), tft.width() - 1, grey);//bottom
  154. tft.drawFastHLine(paddleX, 0, tft.width() - 1, grey);//top
  155. tft.drawFastVLine(tft.width() - 1, 0, tft.height() - (30 + 1), grey);
  156. setScore();
  157. setBallScore(maxBalls);
  158. }
  159. // this function checks the position of the ball
  160. // to see if it intersects with the paddle
  161. boolean inPaddle(int16_t x, int16_t y, int16_t rectX, int16_t rectY, uint8_t rectWidth, uint8_t rectHeight) {
  162. if ((x >= rectX && x <= (rectX + rectWidth)) && (y >= rectY && y <= (rectY + rectHeight))) return true;
  163. return false;
  164. }
  165. void paddleRead(void) {
  166. //uint16_t test = random(100,1024);
  167. uint16_t test = 700;
  168. #if defined(USE_FT5206_TOUCH)
  169. if (tft.touched()) {
  170. tft.updateTS();
  171. uint16_t coordinates[1][2];
  172. tft.getTScoordinates(coordinates);
  173. paddleY = map(coordinates[0][1], 0, tft.width(), (tft.height() - (30 + 1) - (paddleW)), 4);
  174. tft.armTouchISR();
  175. }
  176. #else
  177. int temp = analogRead(A0);
  178. paddleY = map(temp, 0, 1024, (tft.height() - (30 + 1) - (paddleW)), 4);
  179. #endif
  180. //paddleY = map(test, 0, 1024, (tft.height() - (30 + 1) - (paddleW)), 4);
  181. if (oldPaddleY != paddleY) tft.fillRect(paddleX, oldPaddleY, paddleH, paddleW, RA8875_BLACK);
  182. tft.fillRect(paddleX, paddleY, paddleH, paddleW, RA8875_WHITE);
  183. oldPaddleY = paddleY;
  184. }
  185. void setScore() {
  186. tft.setFontScale(0);
  187. tft.setCursor(scoreHumanTextX, scoreTextY);
  188. tft.print(" ");
  189. tft.setCursor(scoreHumanTextX, scoreTextY);
  190. tft.print(humanScore);
  191. tft.setCursor(scoreCpuTextX, scoreTextY);
  192. tft.print(" ");
  193. tft.setCursor(scoreCpuTextX, scoreTextY);
  194. tft.print(cpuScore);
  195. }
  196. void setBallScore(uint8_t ball) {
  197. tft.setFontScale(0);
  198. tft.setCursor(ballTextX, scoreTextY);
  199. tft.print(" ");
  200. tft.setCursor(ballTextX, scoreTextY);
  201. tft.print(ball);
  202. }
  203. void beeper(bool padHit) {
  204. if (padHit) {
  205. tone(BEEPER_PIN, 2000, 20);
  206. } else {
  207. tone(BEEPER_PIN, 3000, 20);
  208. }
  209. }