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

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

Перевод: Максим Кузьмин (Cubewriter) Перевел 364226 статей для сайта.</br>Контакты:</br>* Skype: cubewriter</br>* E-mail: cubewriter@gmail.com</br>* Максим Кузьмин на freelance.ru
Проверка/Оформление/Редактирование: Мякишев Е.А.


Игра в 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 }

См.также

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