Промышленное производство
Промышленный Интернет вещей | Промышленные материалы | Техническое обслуживание и ремонт оборудования | Промышленное программирование |
home  MfgRobots >> Промышленное производство >  >> Manufacturing Technology >> Производственный процесс

Arduino Breakout на сенсорном TFT 2.4″: классическая аркада своими руками

Компоненты и материалы

Компонент Количество Примечание
Arduino UNO 1
AZ-Delivery 2.4" TFT LCD Touch Display Shield (ILI9341, 240x320, 8-бит параллель) 1

Приложения и онлайн-сервисы

О проекте

Мини-версия классического Breakout для Arduino UNO и TFT-экрана 2.4" (240x320), драйвер ILI9341, 8-бит параллельный интерфейс.

Игровой процесс

Несколько уровней с настраиваемым числом строк/столбцов кирпичей (до 8 строк), каждые две строки — свой цвет. Кирпичи можно включать/выключать разными паттернами. Одним мячом, управляя платформой сенсорным экраном, нужно сбить максимум кирпичей, используя стены и/или платформу для рикошета. Промах — потеря жизни.

Очки за строки:

uint8_t pointsForRow[] = {7, 7, 5, 5, 3, 3, 1, 1};

Каждый уровень настраивает размер платформы и мяча. Скорость мяча растёт при каждом ударе. Горизонтальная скорость зависит от точки удара платформы.

Можно добавлять новые уровни с разными паттернами стен:

Arduino Breakout на сенсорном TFT 2.4″: классическая аркада своими руками
Arduino Breakout на сенсорном TFT 2.4″: классическая аркада своими руками
Arduino Breakout на сенсорном TFT 2.4″: классическая аркада своими руками
Arduino Breakout на сенсорном TFT 2.4″: классическая аркада своими руками
Arduino Breakout на сенсорном TFT 2.4″: классическая аркада своими руками
Arduino Breakout на сенсорном TFT 2.4″: классическая аркада своими руками

Как играть

Держите устройство в руках, большими пальцами двигайте платформу влево/вправо по экрану.

Arduino Breakout на сенсорном TFT 2.4″: классическая аркада своими руками

Создание нового уровня

Структура для определения уровня:

typedef struct game_type {
  int ballsize;
  int playerwidth;
  int playerheight;
  int exponent;
  int top;
  int rows;
  int columns;
  int brickGap;
  int lives;
  int wall[GAMES_NUMBER];
  int initVelx;
  int initVely;
} game_type;

Добавить в массив:

game_type games[GAMES_NUMBER] = {
  // ballsize, playerwidth, playerheight, exponent, top, rows, columns, brickGap, lives, wall[8], initVelx, initVely
  { 10, 60, 8, 6, 40 , 8, 8, 3, 3, {0x18, 0x66, 0xFF, 0xDB, 0xFF, 0x7E, 0x24, 0x3C} , 28, -28},
  // ... остальные уровни
};

Паттерн стен

Стена — массив 8x8 бит.

Пример:

{0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA}

Соответствует битовому массиву:

1,0,1,0,1,0,1,0
1,0,1,0,1,0,1,0
... (8 строк)

Результат (зеркалируется):

Arduino Breakout на сенсорном TFT 2.4″: классическая аркада своими руками

Железо

Используется AZ-Delivery 2.4" TFT LCD с резистивным 4-проводным тачскрином и встроенным SD-ридером.

Arduino Breakout на сенсорном TFT 2.4″: классическая аркада своими руками

Подробнее в моей статье «Road testing an AZ-Delivery 2.4 TFT LCD Touch Display».

Сборка шилда

Просто вставляем шилд сверху на Arduino.

Arduino Breakout на сенсорном TFT 2.4″: классическая аркада своими руками
Arduino Breakout на сенсорном TFT 2.4″: классическая аркада своими руками

Библиотеки:

#include <Adafruit_GFX.h>
#include <Adafruit_TFTLCD.h>
#include <TouchScreen.h>

Калибровка тачскрина

Нужно откалибровать, чтобы координаты касания были точными. Библиотека MCUFriend_kbv даёт пример TouchScreen_Calibr_native. Результаты в Serial Monitor. Следуйте инструкциям на экране: нажимайте и удерживайте белые маркеры. После завершения калибровка выводится на экран и в порт.

Для проекта нужны данные PORTRAIT CALIBRATION:

const int XP=8,XM=A2,YP=A3,YM=9; //240x320 ID=0x9341
const int TS_LEFT=118,TS_RT=931,TS_TOP=72,TS_BOT=887;
PORTRAIT CALIBRATION 240 x 320
x = map(p.x, LEFT=118, RT=931, 0, 240)
y = map(p.y, TOP=72, BOT=887, 0, 320)

Анимация

Движение изображения: pos += vel * dt.

Избегание float-арифметики

Разрешение 240x320 → 9 бит на координату. В 16-битном числе 6 бит остаются для дробной части.

Формат: nnnn nnnn nndd dddd — 6 бит = бинарный экспонента. Дробная часть 0.000–0.63. Целая часть — арифметический сдвиг вправо: number >> exponent.

state.ballx += state.velx;
state.bally += state.vely;
checkBallCollisions(game, &state, state.ballx >> game->exponent, state.bally >> game->exponent);
checkBallExit(game, &state, state.ballx >> game->exponent, state.bally >> game->exponent);

Демо-режим

Раскомментируйте #define DEMO_MODE — платформа будет следовать за мячом (как в демо-видео).

Наслаждайтесь!

Создавайте новые паттерны и уровни, делитесь!

Код

Arduino Breakout (Arduino)

/* Arduino Touch TFT Breakout
   Classic breakout game
   Parts: Ardunio UNO + AZ-Delivery 2.4 TFT LCD Touch Shield
   Public domain. Modified 07 11 2020 By Enrique Albertos */
// #define DEMO_MODE
#include <Adafruit_GFX.h>
#include <Adafruit_TFTLCD.h>
#include <TouchScreen.h>

#define BLACK 0x0000
#define BLUE 0x001F
#define RED 0xF800
#define GREEN 0x07E0
#define CYAN 0x07FF
#define MAGENTA 0xF81F
#define YELLOW 0xFFE0
#define WHITE 0xFFFF
#define PRIMARY_COLOR 0x4A11
#define PRIMARY_LIGHT_COLOR 0x7A17
#define PRIMARY_DARK_COLOR 0x4016
#define PRIMARY_TEXT_COLOR 0x7FFF

#define LCD_CS A3
#define LCD_CD A2
#define LCD_WR A1
#define LCD_RD A0
#define LCD_RESET A4
Adafruit_TFTLCD tft(LCD_CS, LCD_CD, LCD_WR, LCD_RD, LCD_RESET);

#define LOWFLASH (defined(__AVR_ATmega328P__) && defined(MCUFRIEND_KBV_H_))
#define MINPRESSURE 40
#define MAXPRESSURE 1000

const int16_t XP = 8, XM = A2, YP = A3, YM = 9;
const int16_t TS_LEFT = 122, TS_RT = 929, TS_TOP = 77, TS_BOT = 884;
const TouchScreen ts = TouchScreen(XP, YP, XM, YM, 300);

#define SCORE_SIZE 30
char scoreFormat[] = "%04d";
typedef struct gameSize_type { int16_t x, y, width, height; } gameSize_type;
gameSize_type gameSize;
uint16_t backgroundColor = BLACK;
int level;
const uint8_t BIT_MASK[] = {0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80};
uint8_t pointsForRow[] = {7, 7, 5, 5, 3, 3, 1, 1};

#define GAMES_NUMBER 16
typedef struct game_type { ... } game_type;
game_type games[GAMES_NUMBER] = { ... }; // 16 уровней

game_type* game;
typedef struct game_state_type { ... } game_state_type;
game_state_type state;

// SETUP
void setup() {
  initTft(tft);
  gameSize = {0, 0, tft.width(), tft.height()};
  newGame(&games[0], &state, tft);
}

// LOOP
int selection = -1;
void loop(void) {
  selection = readUiSelection(game, &state, selection);
  drawPlayer(game, &state);
  state.playerxold = state.playerx;
  // ограничение макс скорости
  if (abs(state.vely) > ((1 << game->exponent) - 1)) state.vely = ((1 << game->exponent) - 1) * ((state.vely > 0) - (state.vely < 0));
  if (abs(state.velx) > ((1 << game->exponent) - 1)) state.velx = ((1 << game->exponent) - 1) * ((state.velx > 0) - (state.velx < 0));
  state.ballx += state.velx;
  state.bally += state.vely;
  checkBallCollisions(game, &state, state.ballx >> game->exponent, state.bally >> game->exponent);
  checkBallExit(game, &state, state.ballx >> game->exponent, state.bally >> game->exponent);
  drawBall(state.ballx >> game->exponent, state.bally >> game->exponent, state.ballxold >> game->exponent, state.ballyold >> game->exponent, game->ballsize);
  state.ballxold = state.ballx; state.ballyold = state.bally;
  // ускорение
  state.velx = (20 + (state.score >> 3)) * ((state.velx > 0) - (state.velx < 0));
  state.vely = (20 + (state.score >> 3)) * ((state.vely > 0) - (state.vely < 0));
  // следующий уровень
  if (noBricks(game, &state) && level < GAMES_NUMBER) {
    level++; newGame(&games[level], &state, tft);
  } else if (state.remainingLives <= 0) {
    gameOverTouchToStart(); state.score = 0; level = 0; newGame(game, &state, tft);
  }
}

// Вспомогательные функции: newGame, setupState, updateLives, setupWall, drawBrick, noBricks, drawPlayer, drawBall, touchToStart, gameOverTouchToStart, updateScore, checkBrickCollision, checkCornerCollision, hitBrick, checkBorderCollision, checkBallCollisions, checkBallExit, setBrick, unsetBrick, isBrickIn, initTft, clearDialog, drawBoxedString, readUiSelection, waitForTouch
// ... (полный код в оригинале)

Схемы

Arduino Breakout на сенсорном TFT 2.4″: классическая аркада своими руками

Производственный процесс

  1. Создание игры в реальном времени на Arduino Nano с гироскопом MPU-6050 и OLED-дисплеем
  2. Создание классической игры Pong на Arduino UNO с OLED-дисплеем: пошаговый урок
  3. Создание портативного ёмкостного сенсорного пианино на Arduino: пошаговое руководство
  4. DIY USB-геймпад на Arduino: собственный высокопроизводительный контроллер
  5. Сборка консоли Pong 24×16 на Arduino Nano и MAX7219
  6. Гигантский анимированный LEGO-человечек: игра «Операция» на Arduino
  7. USB-BLE MIDI-адаптеры на Arduino: беспроводное подключение инструментов к iOS
  8. Pixel Chaser: игра на один тап с NeoPixel Ring и Arduino Nano
  9. Освоение распознавания и синтеза речи на Arduino Due
  10. Автоматизация игры «Динозавр» в Chrome на Arduino и LDR с Python