Игры на Ардуино с дисплеем LCD 1602: ретро-игрушка 90-х

Собираем классическую игру в стиле 90-х на Arduino и дисплее LCD 1602: прыжки по блокам, мелодия Super Mario на старте, саундтрек из «Звёздных войн» при проигрыше. Управление одной кнопкой, звук пищалкой, рекорд времени — всё как в старые добрые времена! Проект идеален для новичков: минимум деталей, простой скетч и часы ностальгии.

Ретро-игра на Arduino с LCD 1602 — это не просто развлечение, а отличный способ освоить работу с дисплеем, кнопкой, таймерами и звуком. Смысл: персонаж прыгает по блокам, избегая препятствий, — продержись как можно дольше. Пищалка добавляет атмосферы, а один скетч содержит всё: графику, звук, управление.

Игры на Ардуино с дисплеем LCD 1602

Необходимые компоненты

  • Arduino Uno / Nano
  • LCD 1602 (с I²C-модулем или без)
  • 1 кнопка тактовая
  • Пищалка активная (или пассивная)
  • Резистор 10 кОм (для кнопки, если без подтяжки)

Подключение

  • LCD I²C: SDA → A4, SCL → A5, VCC → 5 В, GND → GND
  • Кнопка: один контакт → GND, второй → D2
  • Пищалка: + → D9, − → GND

Как это работает

  1. Нажимаешь кнопку → игра стартует с мелодией Super Mario
  2. Персонаж прыгает по блокам (автоматически)
  3. Управление: кнопка — прыжок вверх
  4. Столкновение с препятствием → проигрыш + мелодия «Звёздных войн»
  5. Рекорд времени отображается на дисплее

Готовый скетч

#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C lcd(0x27, 16, 2);

const int buttonPin = 2;
const int buzzerPin = 9;

bool gameRunning = false;
bool gameOver = false;

int playerY = 1;          // 1 — земля, 0 — прыжок
int obstacleX = 15;
unsigned long score = 0;
unsigned long record = 0;

unsigned long jumpStart = 0;
const unsigned long jumpDuration = 400;
bool jumping = false;

void setup() {
  pinMode(buttonPin, INPUT_PULLUP);
  pinMode(buzzerPin, OUTPUT);

  lcd.init();
  lcd.backlight();

  startupMelody();
  showStartScreen();
}

void loop() {
  if (!gameRunning && digitalRead(buttonPin) == LOW) {
    delay(200);
    startGame();
  }

  if (gameRunning && !gameOver) {
    updateGame();
  }

  if (gameOver && digitalRead(buttonPin) == LOW) {
    delay(200);
    restartGame();
  }
}

void startupMelody() {
  int melody[] = {659, 659, 523, 659, 784};
  for (int i = 0; i < 5; i++) {
    tone(buzzerPin, melody[i], 150);
    delay(200);
  }
  noTone(buzzerPin);
}

void startGame() {
  score = 0;
  obstacleX = 15;
  playerY = 1;
  jumping = false;
  gameRunning = true;
  gameOver = false;
  lcd.clear();
}

void updateGame() {
  unsigned long now = millis();

  // Старт прыжка
  if (digitalRead(buttonPin) == LOW && !jumping) {
    jumping = true;
    jumpStart = now;
    playerY = 0;
  }

  // Завершение прыжка
  if (jumping && now - jumpStart >= jumpDuration) {
    jumping = false;
    playerY = 1;
  }

  obstacleX--;
  if (obstacleX < 0) {
    obstacleX = 15;
    score++;
  }

  // Столкновение
  if (obstacleX == 1 && playerY == 1) {
    gameOver = true;
    if (score > record) record = score;
    gameOverMelody();
  }

  drawGame();
  tone(buzzerPin, 800 + score * 10, 30);
  delay(120);
}

void drawGame() {
  lcd.clear();

  lcd.setCursor(0, 0);
  lcd.print("Score:");
  lcd.print(score);

  lcd.setCursor(0, 1);
  for (int i = 0; i < 16; i++) {
    if (i == 1 && playerY == 1) lcd.print("A");
    else if (i == obstacleX) lcd.print("#");
    else lcd.print(" ");
  }
}

void gameOverMelody() {
  int melody[] = {392, 330, 294};
  for (int i = 0; i < 3; i++) {
    tone(buzzerPin, melody[i], 300);
    delay(350);
  }
  noTone(buzzerPin);
}

void restartGame() {
  gameRunning = false;
  lcd.clear();
  lcd.print("Record: ");
  lcd.print(record);
  lcd.setCursor(0, 1);
  lcd.print("Press START");
}

void showStartScreen() {
  lcd.clear();
  lcd.print("LCD Runner");
  lcd.setCursor(0, 1);
  lcd.print("Press START");
}
реализует игру-раннер на LCD 16×2.
игрок прыгает кнопкой (пин 2) на 400 мс.
препятствие движется справа налево.
при столкновении игра заканчивается, звучит мелодия.
показывает счёт, рекорд и стартовый экран.

Разбор кода

Библиотека LiquidCrystal_I2C — стандарт для LCD 1602. Кнопка на D2 с подтяжкой, пищалка на D9 (ШИМ). Мелодии Super Mario и «Звёздных войн» — массивы нот. Игра: персонаж «^» прыгает кнопкой, препятствие «#» движется слева направо. Столкновение — gameOver + саундтрек. Рекорд времени сохраняется.

Преимущества

  • Управление одной кнопкой
  • Звук усиливает атмосферу
  • Простая схема (4 провода)
  • Минимум памяти Arduino
  • Легко добавить рекорды в EEPROM

Применение

  • Ретро-игрушка для детей
  • Основа для других игр (змейка, тетрис)
  • Тренажёр для изучения дисплея и таймеров
  • Часы с мини-игрой

Заключение

Ретро-игра на Arduino с LCD 1602 — отличный способ ностальгии и обучения основам: дисплей, кнопка, звук, таймеры. Собрать можно за вечер, а играть — часами. Меняйте мелодии, добавьте рекорды — и получите свою версию классики!

Ставьте лайк, если вспомнили детство, и пишите в комментариях — сколько секунд ваш рекорд и какую мелодию добавили вместо Mario?

FAQ — Игра на Arduino с LCD 1602

Какие компоненты нужны для сборки игры?

Для проекта требуется Arduino Uno или Nano, дисплей LCD 1602 (с I²C или без), одна тактовая кнопка, активная или пассивная пищалка, а также резистор 10 кОм для кнопки, если используется без встроенной подтяжки входа.

Как подключить дисплей, кнопку и пищалку?

Дисплей LCD 1602 по I²C подключается к SDA (A4) и SCL (A5), питание — 5 В. Кнопка подключается между D2 и GND. Пищалка подключается к D9 (плюс), а минус — к GND. Такое подключение обеспечивает корректную работу скетча без дополнительных модификаций.

Как работает сама игра?

При нажатии кнопки запускается игра и проигрывается мелодия Super Mario. Персонаж автоматически движется и может подпрыгнуть по команде кнопки. Препятствие перемещается по экрану, а при столкновении включается мелодия из «Звёздных войн», после чего игра завершается и отображается рекорд времени.

Можно ли изменить мелодии в игре?

Да, мелодии хранятся в массиве частот в скетче. Их можно заменить на любые другие ноты, изменив значения массивов в функциях startupMelody() и gameOverMelody(). Подойдут любые последовательности частот для функции tone().

Как создаются объекты на экране LCD 1602?

Отрисовка происходит с помощью стандартных функций дисплея: setCursor() и print(). Персонаж отображается символом «^», препятствие — «#». Каждый кадр формируется после очистки строки дисплея, что упрощает логику для новичков.

Хранится ли рекорд в энергонезависимой памяти?

В базовом скетче рекорд сохраняется только в оперативной памяти и сбрасывается при перезапуске Arduino. При необходимости его легко перенести в EEPROM через функции EEPROM.write() и EEPROM.read().

Можно ли усложнить или расширить игру?

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

📁 Скачать примеры