LCD Hill Run v2 – Интерактивная игра-раннер на Arduino с дисплеем 16x2 и зуммером
Компоненты и материалы
| Arduino Mega 2560 | 1 | Или Arduino UNO! Измените DUCK_PIN в коде на 3 и переподключите соответствующе |
| Перемычки (универсальные) | ~20 | |
| Тактильная кнопка 12 мм (SparkFun) | 2 | |
| Резистор 10 кОм | 2 | |
| LCD-дисплей 16x2 (белый на синем, Adafruit) | 1 | |
| Потенциометр 10 кОм | 1 | Любой подходящий |
| Пьезоизлучатель (зуммер) | 1 | Лучше пассивный; активный или пьезо может сработать. Не обязателен для работы, только для звука. НЕ ПОКУПАЙТЕ ПО ССЫЛКЕ — цена $225 ошибочна |
| Бредоборд (полноразмерный рекомендуется) | 1 |
Приложения и онлайн-сервисы
- Arduino IDE (или веб-редактор)
О проекте
Я всего лишь ребёнок и в основном новичок в Arduino. Вдохновившись проектами на Project Hub и изучив основы, я решил создать эту веселую игру. Отладка не заняла много времени, а результат получился очень классным. Код довольно чистый по моим меркам. Наслаждайтесь! Пожалуйста, уважайте труд автора и оставляйте комментарии.
Важно: Скачайте библиотеки, прилагаемые к проекту, и поместите их в папку libraries. Если IDE не находит библиотеку, используйте Скетч → Подключить библиотеку. Библиотеки доступны на GitHub.
Схема подключения
- Arduino +5V → шина питания на бредоборде
- Arduino GND → шина земли
- Кнопка «Прыжок» с 10кОм pull-down к GND, другой контакт → +5V, сигнал → D2
- Кнопка «Присед» с 10кОм pull-down к GND, другой контакт → +5V, сигнал → D18 (на Mega) или D3 (на Uno)
- Пассивный зуммер: один контакт → GND, другой → PWM D5
- LCD 16x2 (стандартное подключение):
- K → GND, A → +5V
- D4–D7 → D9–D12
- E → D8, RW → GND, RS → D7
- V0 → средний контакт потенциометра (контраст), крайние → +5V и GND
- VDD → +5V, VSS → GND
Код (основной скетч)
/* Hill Run v2 — улучшенная версия с прерываниями.
* DUCK_PIN = 18 (на Mega) для работы прерываний; на Uno измените на 3.
* Игра: прыгай через холмы (кнопка Jump) и приседай под воронами (кнопка Duck).
*/
#include <LiquidCrystal.h>
#include "pitches.h"
LiquidCrystal lcd(7, 8, 9, 10, 11, 12);
const int JUMP_PIN = 2;
const int BUZZER_PIN = 5;
const int DUCK_PIN = 18; // На Uno: 3
const int JUMP_PITCH = 2700, JUMP_PITCH_DURATION = 50;
const int DUCK_PITCH = 1350, DUCK_PITCH_DURATION = 50;
const int DIE_PITCH = 200, DIE_PITCH_DURATION = 500;
const int TICKSPEED = 90; // мс за игровой тик
const int JUMP_LENGTH = 3; // символов прыжка
// Спрайты (8x8 байт)
const byte stickStep1[8] = { B01110, B01110, B00101, B11111, B10100, B00110, B11001, B00001 };
const byte stickStep2[8] = { B01110, B01110, B00101, B11111, B10100, B00110, B01011, B01000 };
const byte stickJump[8] = { B01110, B01110, B00100, B11111, B00100, B11111, B10001, B00000 };
const byte stickDuck[8] = { B00000, B00000, B00000, B01110, B01110, B11111, B00100, B11111 };
const byte hill[8] = { B00000, B00100, B01010, B01110, B11101, B10101, B11001, B11111 };
const byte crow1[8] = { B00111, B00100, B00110, B01111, B11111, B01111, B00110, B00111 };
const byte crow2[8] = { B00111, B00110, B01111, B11111, B01111, B00110, B00110, B00111 };
volatile int jumpPhase = JUMP_LENGTH + 1;
int gameTick = 0, crowX = 40, hillX = 25, score = 0;
bool playerY = 0;
volatile bool ducking = LOW;
bool loopBreaker = 1, crowGo = 0;
void setup() {
pinMode(JUMP_PIN, INPUT);
pinMode(BUZZER_PIN, OUTPUT);
lcd.begin(16, 2);
lcd.createChar(0, hill);
lcd.createChar(1, stickStep1);
lcd.createChar(2, stickStep2);
lcd.createChar(3, stickJump);
lcd.createChar(4, stickDuck);
lcd.createChar(5, crow1);
lcd.createChar(6, crow2);
attachInterrupt(digitalPinToInterrupt(JUMP_PIN), seeJumping, RISING);
attachInterrupt(digitalPinToInterrupt(DUCK_PIN), seeDucking, CHANGE);
}
void loop() {
playerY = 0;
if (jumpPhase < JUMP_LENGTH) playerY = 1;
drawSprites();
loopBreaker = 1;
if (hillX < 16) {
if (crowX < hillX) { hillX += 8; loopBreaker = 0; }
if (loopBreaker) { lcd.setCursor(hillX, 1); lcd.write((byte)0); }
}
if (hillX < 1) {
if (jumpPhase < JUMP_LENGTH) { score++; hillX = 16 + random(8); }
else endGame();
}
if (crowX < 16) {
lcd.setCursor(crowX, 0);
lcd.write((byte)(gameTick % 8 < 4 ? 5 : 6));
}
if (crowX < 1) {
if (ducking) { score++; crowX = 24 + random(16); }
else endGame();
}
lcd.setCursor(0, playerY); lcd.print(" ");
jumpPhase++; hillX--; crowGo = !crowGo; crowX -= crowGo; gameTick++;
delay(TICKSPEED);
}
void endGame() {
lcd.clear();
lcd.setCursor(0, 0); lcd.print("Score: ");
lcd.setCursor(7, 0); lcd.print(score);
tone(BUZZER_PIN, DIE_PITCH, DIE_PITCH_DURATION);
while (!digitalRead(JUMP_PIN)) {
lcd.setCursor(0, 1);
if (millis() % 500 < 250) lcd.print("Jump to Continue");
else lcd.print(" ");
}
lcd.clear(); score = 0; hillX = 25; crowX = 40;
}
void drawSprites() {
lcd.setCursor(0, 1 - playerY);
if (!ducking) {
if (!playerY) lcd.write((byte)(gameTick % 4 < 2 ? 1 : 2));
else lcd.write((byte)3);
} else lcd.write((byte)4);
lcd.setCursor(1, 1); lcd.print(" ");
lcd.setCursor(1, 0); lcd.print(" ");
}
void seeJumping() {
if (jumpPhase > (JUMP_LENGTH + 2) && !ducking) {
jumpPhase = 0;
tone(BUZZER_PIN, JUMP_PITCH, JUMP_PITCH_DURATION);
}
}
void seeDucking() {
ducking = digitalRead(DUCK_PIN);
if (ducking) {
jumpPhase = JUMP_LENGTH;
tone(BUZZER_PIN, DUCK_PITCH, DUCK_PITCH_DURATION);
}
}
README (кратко)
Управление: Jump — прыжок через холмы, Duck (удерживать) — присед под воронами. При проигрыше нажмите Jump для рестарта. Счёт = перепрыгнутые холмы + уловленные вороны. Для Uno: в коде измените DUCK_PIN на 3 и переподключите кнопку на D3. Библиотеки: GitHub. Автор: Miles C., 12 лет, лицензия GPL.
Схематика (Fritzing)
Файл: hillrun2_zp0SI4wns3.fzz. На схеме показано подключение всех компонентов. Для Uno — см. примечание про DUCK_PIN.
Производственный процесс
- Создание игры в реальном времени на Arduino Nano с гироскопом MPU-6050 и OLED-дисплеем
- Создание классической игры Pong на Arduino UNO с OLED-дисплеем: пошаговый урок
- DIY USB-геймпад на Arduino: собственный высокопроизводительный контроллер
- Создание анимации и игр на LCD 16×2 с Arduino UNO
- Arduino Breakout на сенсорном TFT 2.4″: классическая аркада своими руками
- Pixel Chaser: игра на один тап с NeoPixel Ring и Arduino Nano
- Автоматизация игры «Динозавр» в Chrome на Arduino и LDR с Python
- DIY LED-рулетка — собираем одноигровой аркадный автомат на Arduino Nano
- Карманная игровая консоль на Arduino Pro Mini: лабиринт A-Maze
- Надежная погодная станция на Arduino с датчиками DHT