Cat hungry.png
Здравствуйте! Собираем деньги на перевод материалов по электронике(https://www.allaboutcircuits.com/education/). Реквизиты указаны здесь.

Arduino:Примеры/Esplora TFT Pong

Материал из Онлайн справочника
Перейти к: навигация, поиск

Перевод: Максим Кузьмин (Cubewriter)
Перевел 2686 статей для сайта.

Контакты:

Проверка/Оформление/Редактирование: Мякишев Е.А.


Игра в Pong на TFT-экране Esplora[1]

Этот пример для платы Arduino (и подключенного к ней TFT-экрана Arduino) является упрощенной вариацией на тему игры Pong.

Скетч создает два объекта – прямоугольную платформу, которая может двигаться в двух направлениях, а также мячик, отскакивающий и от краев экрана, и от платформы. Скорость мяча регулируется встроенным слайдером Esplora.

Этот пример демонстрирует использование так называемого «обнаружения столкновений» объектов на экране, а также то, как быстро обновить картинки без необходимости при каждом проходе через loop() стирать весь экран.

Необходимое оборудование

  • Плата Arduino Esplora;
  • TFT-экран Arduino;

Цепь

Esplora GLCDPong.png

Подключите TFT-экран к сокету на Esplora – так, чтобы надпись «SD Card» смотрела вверх.

Код

Чтобы использовать экран, сначала нужно подключить библиотеки TFT и SPI. Кроме того, нам понадобится библиотека Esplora.

  1. #include <Esplora.h>
  2. #include <TFT.h>
  3. #include <SPI.h>

Задаем несколько переменных – координаты (X и Y) для мячика и платформы, направление мяча, а также предыдущие координаты (X и Y) мячика и платформы.

  1. int paddleX = 0;
  2. int paddleY = 0;
  3. int oldPaddleX, oldPaddleY;
  4. int ballDirectionX = 1;
  5. int ballDirectionY = 1;
  6.  
  7. int ballX, ballY, oldBallX, oldBallY;

В секции setup() запускаем последовательную передачу данных, инициализируем дисплей и очищаем фон экрана.

  1. void setup() {
  2.   Serial.begin(9600);
  3.   EsploraTFT.begin();
  4.   EsploraTFT.background(0,0,0);
  5. }

В блоке loop() будет код для считывания данных от джойстика, затем стирание предыдущей позиции платформы и, наконец, прорисовка новой позиции платформы.

  1. void loop() {
  2.   int myWidth = EsploraTFT.width();
  3.   int myHeight = EsploraTFT.height();
  4.  
  5.   paddleX = map(Esplora.readJoystickX(), 512, -512, 0, myWidth) - 20/2;
  6.   paddleY = map(Esplora.readJoystickY(), -512, 512, 0, myHeight) - 5/2;
  7.   Serial.print(paddleX);
  8.   Serial.print(" ");
  9.   Serial.println(paddleY);
  10.  
  11.   EsploraTFT.fill(0,0,0);
  12.  
  13.   if (oldPaddleX != paddleX || oldPaddleY != paddleY) {
  14.     EsploraTFT.rect(oldPaddleX, oldPaddleY, 20, 5);
  15.   }
  16.  
  17.   EsploraTFT.fill(255,255,255);
  18.   EsploraTFT.rect(paddleX, paddleY, 20, 5);

Сохраняем текущие координаты платформы как предыдущие, чтобы в следующий раз можно было проверить, переместилась платформа или нет.

  1. oldPaddleX = paddleX;
  2.   oldPaddleY = paddleY;

В конце блока loop() считываем позицию слайдера, чтобы определить скорость мяча. Также вызываем пользовательскую функцию под названием moveBall() – с ее помощью мы будем обновлять позицию мяча.

  1. int ballSpeed = map(Esplora.readSlider(), 0, 1023, 0, 80)+1;
  2.   if (millis() % ballSpeed < 2) {
  3.     moveBall();
  4.   }
  5. }

Это обновление будет проходить следующим образом – сначала функция moveBall() сотрет старое месторасположение мяча, а затем нарисует его в новом месте. Кроме того, эта же функция будет следить, чтобы мячик не улетел за край экрана, т.е. как только мяча долетит до границ дисплея, она реверсирует его направление.

  1. void moveBall() {
  2.   if (ballX > EsploraTFT.width() || ballX < 0) {
  3.     ballDirectionX = -ballDirectionX;
  4.   }
  5.   if (ballY > EsploraTFT.height() || ballY < 0) {
  6.     ballDirectionY = -ballDirectionY;
  7.   }  
  8.   if (inPaddle(ballX, ballY, paddleX, paddleY, 20, 5)) {
  9.     ballDirectionY = -ballDirectionY;
  10.   }
  11.  
  12.   ballX += ballDirectionX;
  13.   ballY += ballDirectionY;
  14.  
  15.   EsploraLCD.fill(0,0,0);
  16.  
  17.   if (oldBallX != ballX || oldBallY != ballY) {
  18.     EsploraTFT.rect(oldBallX, oldBallY, 5, 5);
  19.   }
  20.  
  21.   EsploraLCD.fill(255,255,255);
  22.   EsploraLCD.rect(ballX, ballY, 5, 5);
  23.  
  24.   oldBallX = ballX;
  25.   oldBallY = ballY;
  26. }

Кроме того, нам понадобится еще одна пользовательская функция, которая будет следить за пересечением мяча и платформы – назовем ее inPaddle(). Она будет проверять, не занимают ли мяч и платформа одно и то же место в пространстве. Если да, она вернет значение TRUE, а затем реверсирует направление мяча, как если бы он ударился о границу экрана.

  1. boolean inPaddle(int x, int y, int rectX, int rectY, int rectWidth, int rectHeight) {
  2.   boolean result = false;
  3.  
  4.   if ((x >= rectX && x <= (rectX + rectWidth)) &&
  5.     (y >= rectY && y <= (rectY + rectHeight))) {
  6.     result = true;
  7.   }
  8.   return result;  
  9. }

Весь код полностью – ниже:

  1. /*
  2. Игра в Pong на TFT-экране Esplora
  3.  
  4. Это пример для платы Esplora и TFT-экрана Arduino.
  5. Он считывает данные, поступающие от джойстика, чтобы перемещать
  6. прямоугольную платформу по осям X и Y. Платформа может
  7. взаимодействовать с мячом – ударившись о нее, он будет отскакивать.
  8. Скорость мяча регулируется линейным потенциометром Esplora.
  9.  
  10. Этот код не защищен авторским правом.
  11.  
  12. Создан в декабре 2012 Томом Иго (Tom Igoe),
  13. модифицирован 15 апреля 2013 Скоттом Фитцджеральдом (Scott Fitzgerald).
  14.  
  15. http://www.arduino.cc/en/Tutorial/EsploraTFTPong
  16. */
  17.  
  18. #include <Esplora.h>
  19. #include <TFT.h>            // библиотека для TFT-экрана Arduino
  20. #include <SPI.h>
  21.  
  22. // переменные для координат мяча и платформы:
  23. int paddleX = 0;
  24. int paddleY = 0;
  25. int oldPaddleX, oldPaddleY;
  26. int ballDirectionX = 1;
  27. int ballDirectionY = 1;
  28.  
  29. int ballX, ballY, oldBallX, oldBallY;
  30.  
  31. void setup() {
  32.  
  33.   Serial.begin(9600);
  34.  
  35.   // Инициализируем дисплей:
  36.   EsploraTFT.begin();
  37.   // Закрашиваем фон черным цветом:
  38.   EsploraTFT.background(0, 0, 0);
  39. }
  40.  
  41. void loop() {
  42.   // Сохраняем ширину и высоту экрана:
  43.   int myWidth = EsploraTFT.width();
  44.   int myHeight = EsploraTFT.height();
  45.  
  46.   // Приспосабливаем диапазон хода джойстика к размерам экрана:
  47.   paddleX = map(Esplora.readJoystickX(), 512, -512, 0, myWidth) - 20 / 2;
  48.   paddleY = map(Esplora.readJoystickY(), -512, 512, 0, myHeight) - 5 / 2;
  49.   Serial.print(paddleX);
  50.   Serial.print(" ");
  51.   Serial.println(paddleY);
  52.  
  53.   // Делаем цвет заливки черным и стираем предыдущую позицию платформы,
  54.   // если она отличается от текущей:
  55.   EsploraTFT.fill(0, 0, 0);
  56.  
  57.   if (oldPaddleX != paddleX || oldPaddleY != paddleY) {
  58.     EsploraTFT.rect(oldPaddleX, oldPaddleY, 20, 5);
  59.   }
  60.  
  61.   // Рисуем на экране платформу, сохраняем ее текущую позицию как предыдущую:
  62.   EsploraTFT.fill(255, 255, 255);
  63.   EsploraTFT.rect(paddleX, paddleY, 20, 5);
  64.   oldPaddleX = paddleX;
  65.   oldPaddleY = paddleY;
  66.  
  67.   // Считываем данные от слайдера, чтобы определить скорость мяча:
  68.   int ballSpeed = map(Esplora.readSlider(), 0, 1023, 0, 80) + 1;
  69.   if (millis() % ballSpeed < 2) {
  70.     moveBall();
  71.   }
  72. }
  73.  
  74. // Функция для определения позиции мяча на экране:
  75. void moveBall() {
  76.   // Если мяч улетел за пределы экрана, реверсируем его направление:
  77.   if (ballX > EsploraTFT.width() || ballX < 0) {
  78.     ballDirectionX = -ballDirectionX;
  79.   }
  80.  
  81.   if (ballY > EsploraTFT.height() || ballY < 0) {
  82.     ballDirectionY = -ballDirectionY;
  83.   }
  84.  
  85.   // Проверяем, не занимают ли платформа и мяч одно и то же место в пространстве:
  86.   if (inPaddle(ballX, ballY, paddleX, paddleY, 20, 5)) {
  87.     ballDirectionY = -ballDirectionY;
  88.   }
  89.  
  90.   // Обновляем позицию мяча:
  91.   ballX += ballDirectionX;
  92.   ballY += ballDirectionY;
  93.  
  94.   // Стираем предыдущую позицию мяча:
  95.   EsploraTFT.fill(0, 0, 0);
  96.  
  97.   if (oldBallX != ballX || oldBallY != ballY) {
  98.     EsploraTFT.rect(oldBallX, oldBallY, 5, 5);
  99.   }
  100.  
  101.   // Рисуем текущую позицию мяча:
  102.   EsploraTFT.fill(255, 255, 255);
  103.  
  104.   EsploraTFT.rect(ballX, ballY, 5, 5);
  105.  
  106.   oldBallX = ballX;
  107.   oldBallY = ballY;
  108.  
  109. }
  110.  
  111. // Функция для проверки того, не пересекаются ли позиции мяча и платформы:
  112. boolean inPaddle(int x, int y, int rectX, int rectY, int rectWidth, int rectHeight) {
  113.   boolean result = false;
  114.  
  115.   if ((x >= rectX && x <= (rectX + rectWidth)) &&
  116.       (y >= rectY && y <= (rectY + rectHeight))) {
  117.     result = true;
  118.   }
  119.  
  120.   return result;
  121. }

См.также

Внешние ссылки

  1. Arduino - Esplora TFT Pong