Уроки

Делаем игровую консоль с арканоидом на Ардуино

Нет комментариев

Создадим игровую консоль с игрой "арканоид" на основе Arduino UNO с TFT LCD экраном (240x320 пикселей), драйвером ILI9341 с 8-битной параллельной связью.

Демонстрация

Демонстрация игровой консоли представлена на видео ниже. Данный урок был опубликован благодаря поддержке бюро АСК Лаб - лаборатории по разработке электронных устройств на заказ.

Компоненты

Для создания нашей игровой консоли нам нужны будут следующие компоненты:

  1. Arduino Uno
  2. AZ-Delivery 2,4-дюймовый TFT ЖК-дисплей и шилд

В этом проекте используется 2,4-дюймовый TFT ЖК-дисплей AZ-Delivery с резистивным 4-проводным сенсорным экраном и встроенным устройством чтения SD-карт.

Из программного обеспечения нам традиционно нужна среда разработки Arduino IDE.

Сборка игровой консоли

С распиновкой нашего шилда можно ознакомиться ниже:

Чтобы собрать нашу игровую консоль всё что нам нужно только соединить экран с нашей платой Arduino Uno.

Игра

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

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

Если ракетка игрока не попадает по мячу, - игрок теряет ход. Каждый кирпичик ряда приносит разные очки:

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

На каждом уровне можно настроить размер ракетки и размер мяча. Скорость мяча увеличивается с каждым ударом, вы можете настроить начальную скорость для каждого экрана. В зависимости от того, под каким углом падает мяч на ракетку и в какое место, - изменяется скорость мяча.

Вы можете определить различный вид игровых экранов:

Как играть?

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

Код проекта

Скачать файл .ino для игровой консоли вы можете ниже. Код проекта целиком:

Определение нового экрана

Эта структура используется для определения нового экрана:

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
1,0,1,0,1,0,1,0
1,0,1,0,1,0,1,0
1,0,1,0,1,0,1,0
1,0,1,0,1,0,1,0
1,0,1,0,1,0,1,0
1,0,1,0,1,0,1,0

Получаем в итоге такую стену (обратите внимание, что она зеркальная):

Библиотеки

В начале программы мы подключаем нужные нам библиотеки:

#include <Adafruit_GFX.h>    // Core graphics library
#include <Adafruit_TFTLCD.h>
#include <TouchScreen.h>

Калибровка сенсорного экрана

Вы должны откалибровать дисплей так, чтобы информация о местоположении была правильной при прикосновении к дисплею. Библиотека MCUFriend_kbv предоставляет пример с именем «TouchScreen_Calibr_native».

Пример отправляет результаты в последовательный порт. Запустите последовательный монитор IDE Arduino, чтобы вы могли скопировать код, созданный в примере.

Следуйте инструкциям на сенсорном дисплее, нажмите и удерживайте отображаемые маркеры положения, которые выделены белым. После того, как вы закончите с отметками положения, калибровка дисплея выводится вам на сенсорный дисплей и через последовательный порт.

Для этого проекта вам понадобятся данные для «портретной калибровки».

TouchScreen.h GFX Calibration
Making all control and bus pins INPUT_PULLUP
Typical 30k Analog pullup with corresponding pin
would read low when digital is written LOW
e.g. reads ~25 for 300R X direction
e.g. reads ~30 for 500R Y direction
Testing : (A2, D8) = 26
Testing : (A3, D9) = 28
ID = 0x9341
cx=153 cy=103 cz=534  X, Y, Pressure
cx=150 cy=475 cz=406  X, Y, Pressure
cx=155 cy=868 cz=231  X, Y, Pressure
cx=517 cy=103 cz=561  X, Y, Pressure
cx=535 cy=855 cz=364  X, Y, Pressure
cx=884 cy=88 cz=650  X, Y, Pressure
cx=908 cy=478 cz=557  X, Y, Pressure
cx=902 cy=864 cz=488  X, Y, Pressure
*** COPY-PASTE from Serial Terminal:
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)
LANDSCAPE CALIBRATION     320 x 240
x = map(p.y, LEFT=72, RT=887, 0, 320)
y = map(p.x, TOP=931, BOT=118, 0, 240)

Анимация

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

pos += vel * dt;

Избегаем арифметики с плавающей запятой

Разрешение ILI9341 составляет 240 x 320, поэтому нам нужны два 9-битных целых числа для ссылки на пиксель на экране. Использование 16-битных целых чисел позволяет освободить 6 бит для представления десятичной части.

nnnn nnnn nndd dddd

Мы называем это число 6 двоичной экспонентой. И мы можем использовать эти шесть битов для получения десятичной части от 0,000 до 0,63. Таким образом, мы можем использовать целочисленную математику, избегая арифметики с плавающей запятой.

Чтобы получить целую часть числа, делаем арифметический сдвиг вправо.

число >> экспонента (number >> exponent)

state.ballx += state.velx;
  state.bally += state.vely;

  // check ball collisions and exit
  checkBallCollisions(game, &state, state.ballx >> game->exponent, state.bally >> game->exponent);
  checkBallExit(game, &state, state.ballx >> game->exponent, state.bally >> game->exponent);

Демо-режим

Раскомментируйте директиву define, и ракетка будет следовать за мячом, как показано в демо-видео:

#define DEMO_MODE

Теперь вы можете самостоятельно создавать новые шаблоны, уровни и усложнять игру.

Оригинал

Поделиться
25 ноября 2020 в 18:11
Обновлено 19 января 2021 в 01:02 (редакция)
Опубликовано:
Уроки,

Добавить комментарий

Ваш E-mail не будет никому виден. Обязательные поля отмечены *