Arduino:Примеры/Esplora TFT Pong
Содержание | Знакомство с Arduino | Продукты | Основы | Справочник языка Arduino | Примеры | Библиотеки | Хакинг | Изменения | Сравнение языков Arduino и Processing |
Игра в Pong на TFT-экране Esplora[1]
Этот пример для платы Arduino (и подключенного к ней TFT-экрана Arduino) является упрощенной вариацией на тему игры Pong.
Скетч создает два объекта – прямоугольную платформу, которая может двигаться в двух направлениях, а также мячик, отскакивающий и от краев экрана, и от платформы. Скорость мяча регулируется встроенным слайдером Esplora.
Этот пример демонстрирует использование так называемого «обнаружения столкновений» объектов на экране, а также то, как быстро обновить картинки без необходимости при каждом проходе через loop() стирать весь экран.
Необходимое оборудование
- Плата Arduino Esplora;
- TFT-экран Arduino;
Цепь
Подключите TFT-экран к сокету на Esplora – так, чтобы надпись «SD Card» смотрела вверх.
Код
Чтобы использовать экран, сначала нужно подключить библиотеки TFT и SPI. Кроме того, нам понадобится библиотека Esplora.
#include <Esplora.h>
#include <TFT.h>
#include <SPI.h>
Задаем несколько переменных – координаты (X и Y) для мячика и платформы, направление мяча, а также предыдущие координаты (X и Y) мячика и платформы.
int paddleX = 0;
int paddleY = 0;
int oldPaddleX, oldPaddleY;
int ballDirectionX = 1;
int ballDirectionY = 1;
int ballX, ballY, oldBallX, oldBallY;
В секции setup() запускаем последовательную передачу данных, инициализируем дисплей и очищаем фон экрана.
void setup() {
Serial.begin(9600);
EsploraTFT.begin();
EsploraTFT.background(0,0,0);
}
В блоке loop() будет код для считывания данных от джойстика, затем стирание предыдущей позиции платформы и, наконец, прорисовка новой позиции платформы.
void loop() {
int myWidth = EsploraTFT.width();
int myHeight = EsploraTFT.height();
paddleX = map(Esplora.readJoystickX(), 512, -512, 0, myWidth) - 20/2;
paddleY = map(Esplora.readJoystickY(), -512, 512, 0, myHeight) - 5/2;
Serial.print(paddleX);
Serial.print(" ");
Serial.println(paddleY);
EsploraTFT.fill(0,0,0);
if (oldPaddleX != paddleX || oldPaddleY != paddleY) {
EsploraTFT.rect(oldPaddleX, oldPaddleY, 20, 5);
}
EsploraTFT.fill(255,255,255);
EsploraTFT.rect(paddleX, paddleY, 20, 5);
Сохраняем текущие координаты платформы как предыдущие, чтобы в следующий раз можно было проверить, переместилась платформа или нет.
oldPaddleX = paddleX;
oldPaddleY = paddleY;
В конце блока loop() считываем позицию слайдера, чтобы определить скорость мяча. Также вызываем пользовательскую функцию под названием moveBall() – с ее помощью мы будем обновлять позицию мяча.
int ballSpeed = map(Esplora.readSlider(), 0, 1023, 0, 80)+1;
if (millis() % ballSpeed < 2) {
moveBall();
}
}
Это обновление будет проходить следующим образом – сначала функция moveBall() сотрет старое месторасположение мяча, а затем нарисует его в новом месте. Кроме того, эта же функция будет следить, чтобы мячик не улетел за край экрана, т.е. как только мяча долетит до границ дисплея, она реверсирует его направление.
void moveBall() {
if (ballX > EsploraTFT.width() || ballX < 0) {
ballDirectionX = -ballDirectionX;
}
if (ballY > EsploraTFT.height() || ballY < 0) {
ballDirectionY = -ballDirectionY;
}
if (inPaddle(ballX, ballY, paddleX, paddleY, 20, 5)) {
ballDirectionY = -ballDirectionY;
}
ballX += ballDirectionX;
ballY += ballDirectionY;
EsploraLCD.fill(0,0,0);
if (oldBallX != ballX || oldBallY != ballY) {
EsploraTFT.rect(oldBallX, oldBallY, 5, 5);
}
EsploraLCD.fill(255,255,255);
EsploraLCD.rect(ballX, ballY, 5, 5);
oldBallX = ballX;
oldBallY = ballY;
}
Кроме того, нам понадобится еще одна пользовательская функция, которая будет следить за пересечением мяча и платформы – назовем ее inPaddle(). Она будет проверять, не занимают ли мяч и платформа одно и то же место в пространстве. Если да, она вернет значение TRUE, а затем реверсирует направление мяча, как если бы он ударился о границу экрана.
boolean inPaddle(int x, int y, int rectX, int rectY, int rectWidth, int rectHeight) {
boolean result = false;
if ((x >= rectX && x <= (rectX + rectWidth)) &&
(y >= rectY && y <= (rectY + rectHeight))) {
result = true;
}
return result;
}
Весь код полностью – ниже:
/*
Игра в Pong на TFT-экране Esplora
Это пример для платы Esplora и TFT-экрана Arduino.
Он считывает данные, поступающие от джойстика, чтобы перемещать
прямоугольную платформу по осям X и Y. Платформа может
взаимодействовать с мячом – ударившись о нее, он будет отскакивать.
Скорость мяча регулируется линейным потенциометром Esplora.
Этот код не защищен авторским правом.
Создан в декабре 2012 Томом Иго (Tom Igoe),
модифицирован 15 апреля 2013 Скоттом Фитцджеральдом (Scott Fitzgerald).
http://www.arduino.cc/en/Tutorial/EsploraTFTPong
*/
#include <Esplora.h>
#include <TFT.h> // библиотека для TFT-экрана Arduino
#include <SPI.h>
// переменные для координат мяча и платформы:
int paddleX = 0;
int paddleY = 0;
int oldPaddleX, oldPaddleY;
int ballDirectionX = 1;
int ballDirectionY = 1;
int ballX, ballY, oldBallX, oldBallY;
void setup() {
Serial.begin(9600);
// Инициализируем дисплей:
EsploraTFT.begin();
// Закрашиваем фон черным цветом:
EsploraTFT.background(0, 0, 0);
}
void loop() {
// Сохраняем ширину и высоту экрана:
int myWidth = EsploraTFT.width();
int myHeight = EsploraTFT.height();
// Приспосабливаем диапазон хода джойстика к размерам экрана:
paddleX = map(Esplora.readJoystickX(), 512, -512, 0, myWidth) - 20 / 2;
paddleY = map(Esplora.readJoystickY(), -512, 512, 0, myHeight) - 5 / 2;
Serial.print(paddleX);
Serial.print(" ");
Serial.println(paddleY);
// Делаем цвет заливки черным и стираем предыдущую позицию платформы,
// если она отличается от текущей:
EsploraTFT.fill(0, 0, 0);
if (oldPaddleX != paddleX || oldPaddleY != paddleY) {
EsploraTFT.rect(oldPaddleX, oldPaddleY, 20, 5);
}
// Рисуем на экране платформу, сохраняем ее текущую позицию как предыдущую:
EsploraTFT.fill(255, 255, 255);
EsploraTFT.rect(paddleX, paddleY, 20, 5);
oldPaddleX = paddleX;
oldPaddleY = paddleY;
// Считываем данные от слайдера, чтобы определить скорость мяча:
int ballSpeed = map(Esplora.readSlider(), 0, 1023, 0, 80) + 1;
if (millis() % ballSpeed < 2) {
moveBall();
}
}
// Функция для определения позиции мяча на экране:
void moveBall() {
// Если мяч улетел за пределы экрана, реверсируем его направление:
if (ballX > EsploraTFT.width() || ballX < 0) {
ballDirectionX = -ballDirectionX;
}
if (ballY > EsploraTFT.height() || ballY < 0) {
ballDirectionY = -ballDirectionY;
}
// Проверяем, не занимают ли платформа и мяч одно и то же место в пространстве:
if (inPaddle(ballX, ballY, paddleX, paddleY, 20, 5)) {
ballDirectionY = -ballDirectionY;
}
// Обновляем позицию мяча:
ballX += ballDirectionX;
ballY += ballDirectionY;
// Стираем предыдущую позицию мяча:
EsploraTFT.fill(0, 0, 0);
if (oldBallX != ballX || oldBallY != ballY) {
EsploraTFT.rect(oldBallX, oldBallY, 5, 5);
}
// Рисуем текущую позицию мяча:
EsploraTFT.fill(255, 255, 255);
EsploraTFT.rect(ballX, ballY, 5, 5);
oldBallX = ballX;
oldBallY = ballY;
}
// Функция для проверки того, не пересекаются ли позиции мяча и платформы:
boolean inPaddle(int x, int y, int rectX, int rectY, int rectWidth, int rectHeight) {
boolean result = false;
if ((x >= rectX && x <= (rectX + rectWidth)) &&
(y >= rectY && y <= (rectY + rectHeight))) {
result = true;
}
return result;
}