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.

pingpong.ino 6.3KB

3 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251
  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. // begin display: Choose from: RA8875_480x272, RA8875_800x480, RA8875_800x480ALT, Adafruit_480x272, Adafruit_800x480
  47. tft.begin(RA8875_800x480);
  48. #if defined(USE_FT5206_TOUCH)
  49. tft.setTouchLimit(1);
  50. tft.armTouchISR(true);//touch screen interrupt it's armed
  51. #endif
  52. scoreTextY = tft.height() - (30 + 1 + (ballSize + 1)) + 15;
  53. }
  54. void loop() {
  55. if (restart) {
  56. restart = false;
  57. restartGame();
  58. }
  59. paddleRead();
  60. // update the ball's position and draw it on screen
  61. if (millis() % ballSpeed < 2) moveBall();
  62. }
  63. void moveBall() {
  64. bool started = false;
  65. if (launchBall) {
  66. launchBall = false;
  67. ballDirX = random(1, 5);
  68. ballDirY = random(1, 5);
  69. ballX = (tft.width() - 1) - (ballSize + ballDirY) ;
  70. ballY = (tft.height() / 2) + random(-30, 30);
  71. oldBallX = -1;
  72. oldBallY = -1;
  73. started = true;
  74. } else {
  75. bool reverseDirX = false;
  76. bool reverseDirY = false;
  77. if (ballX > tft.width() - (ballSize + 2)) reverseDirX = true;//RIGHT
  78. if (ballX < 0) {//missed ball!--------------------------------------
  79. tft.fillRect(oldBallX, oldBallY, ballSize, ballSize, RA8875_BLACK);
  80. tft.drawFastVLine(tft.width() - 1, 0, tft.height() - (30 + 1), grey);
  81. tone(BEEPER_PIN, 800, 100);
  82. launchBall = true;
  83. //delay(1000);
  84. maxBalls--;
  85. cpuScore += 100;
  86. setScore();
  87. if (maxBalls < 1) {
  88. tft.setCursor(CENTER, CENTER);
  89. tft.setFontScale(2);
  90. if (cpuScore > humanScore) {
  91. tft.print("YOU LOOSE!");
  92. } else if (cpuScore == humanScore) {
  93. tft.print("PARITY!");
  94. } else {
  95. tft.print("YOU WIN!");
  96. }
  97. setBallScore(0);
  98. setScore();
  99. delay(5000);
  100. tft.fillWindow();
  101. restart = true;
  102. return;
  103. } else {
  104. setBallScore(maxBalls);
  105. delay(1000);
  106. return;
  107. }
  108. }
  109. if (reverseDirX) {
  110. ballDirX = -ballDirX;
  111. beeper(false);
  112. }
  113. if ((ballY > tft.height() - (30 + 1 + (ballSize + 5)))) reverseDirY = true;//BOTTOM
  114. if (ballY < (ballSize)) reverseDirY = true;//TOP
  115. if (reverseDirY) {
  116. ballDirY = -ballDirY;
  117. beeper(false);
  118. }
  119. if (inPaddle(ballX, ballY, paddleX, paddleY, paddleH, paddleW)) {
  120. beeper(true);
  121. humanScore += 100;
  122. setScore();
  123. ballDirX = -ballDirX;
  124. ballDirY = -ballDirY;
  125. }
  126. ballX += ballDirX;
  127. ballY += ballDirY;
  128. }
  129. if (oldBallX != ballX || oldBallY != ballY) tft.fillRect(oldBallX, oldBallY, ballSize, ballSize, RA8875_BLACK);
  130. tft.fillRect(ballX, ballY, ballSize, ballSize, ballColor);
  131. if (started)tft.drawFastVLine(tft.width() - 1, 0, tft.height() - (30 + 1), grey);
  132. oldBallX = ballX;
  133. oldBallY = ballY;
  134. }
  135. void restartGame() {
  136. humanScore = 0;
  137. cpuScore = 0;
  138. maxBalls = 10;
  139. launchBall = true;
  140. //tft.clearScreen();
  141. tft.setFontScale(0);
  142. tft.setTextColor(RA8875_WHITE, RA8875_BLACK);
  143. tft.setCursor(30, scoreTextY);
  144. tft.print("Human: ");
  145. scoreHumanTextX = tft.getCursorX();
  146. tft.setCursor(120, scoreTextY);
  147. tft.print("CPU: ");
  148. scoreCpuTextX = tft.getCursorX();
  149. tft.setCursor(200, scoreTextY);
  150. tft.print("BALL: ");
  151. ballTextX = tft.getCursorX();
  152. tft.setCursor(tft.width() - 120, scoreTextY);
  153. tft.print("[ Damn Pong! ] ");
  154. tft.drawFastHLine(paddleX, tft.height() - (30 + 1), tft.width() - 1, grey);//bottom
  155. tft.drawFastHLine(paddleX, 0, tft.width() - 1, grey);//top
  156. tft.drawFastVLine(tft.width() - 1, 0, tft.height() - (30 + 1), grey);
  157. setScore();
  158. setBallScore(maxBalls);
  159. }
  160. // this function checks the position of the ball
  161. // to see if it intersects with the paddle
  162. boolean inPaddle(int16_t x, int16_t y, int16_t rectX, int16_t rectY, uint8_t rectWidth, uint8_t rectHeight) {
  163. if ((x >= rectX && x <= (rectX + rectWidth)) && (y >= rectY && y <= (rectY + rectHeight))) return true;
  164. return false;
  165. }
  166. void paddleRead(void) {
  167. //uint16_t test = random(100,1024);
  168. //uint16_t test = 700;
  169. #if defined(USE_FT5206_TOUCH)
  170. if (tft.touched()) {
  171. tft.updateTS();
  172. uint16_t coordinates[1][2];
  173. tft.getTScoordinates(coordinates);
  174. paddleY = map(coordinates[0][1], 0, tft.width(), (tft.height() - (30 + 1) - (paddleW)), 4);
  175. tft.armTouchISR();
  176. }
  177. #else
  178. int temp = analogRead(A0);
  179. paddleY = map(temp, 0, 1024, (tft.height() - (30 + 1) - (paddleW)), 4);
  180. #endif
  181. //paddleY = map(test, 0, 1024, (tft.height() - (30 + 1) - (paddleW)), 4);
  182. if (oldPaddleY != paddleY) tft.fillRect(paddleX, oldPaddleY, paddleH, paddleW, RA8875_BLACK);
  183. tft.fillRect(paddleX, paddleY, paddleH, paddleW, RA8875_WHITE);
  184. oldPaddleY = paddleY;
  185. }
  186. void setScore() {
  187. tft.setFontScale(0);
  188. tft.setCursor(scoreHumanTextX, scoreTextY);
  189. tft.print(" ");
  190. tft.setCursor(scoreHumanTextX, scoreTextY);
  191. tft.print(humanScore);
  192. tft.setCursor(scoreCpuTextX, scoreTextY);
  193. tft.print(" ");
  194. tft.setCursor(scoreCpuTextX, scoreTextY);
  195. tft.print(cpuScore);
  196. }
  197. void setBallScore(uint8_t ball) {
  198. tft.setFontScale(0);
  199. tft.setCursor(ballTextX, scoreTextY);
  200. tft.print(" ");
  201. tft.setCursor(ballTextX, scoreTextY);
  202. tft.print(ball);
  203. }
  204. void beeper(bool padHit) {
  205. if (padHit) {
  206. tone(BEEPER_PIN, 2000, 20);
  207. } else {
  208. tone(BEEPER_PIN, 3000, 20);
  209. }
  210. }