Dino Run на ESP32 и OLED 0.96: Часть 1 — Пошаговый гайд

Dino Run на ESP32: Создаем игру на OLED 0.96 (Часть 1). Запускаем игру из Chrome своими руками

У каждого мейкера в ящике валяется пара лишних ESP32 и тот самый крошечный OLED-дисплей 0.96″, с которого начинаются 90% всех DIY-проектов. Сегодня мы заставим это железо работать на полную: мы портируем легендарного Динозаврика из Chrome на ESP32. В этой части мы не просто запустим игру, но и разберем, как реализовать физику прыжка в условиях ограниченных ресурсов микроконтроллера. А если у вас нет под рукой деталей — вы сможете запустить мой код в онлайн-симуляторе за один клик.

Железо и схема подключения

Для первой части нашего проекта мы будем использовать максимально доступные компоненты. I2C интерфейс позволяет подключить экран всего по двум сигнальным проводам.

Список компонентов:

  • ESP32 DevKit V1
  • OLED 0.96″ (SSD1306)
  • Кнопка (Tactile Switch)
  • Макетная плата
  • Провода для подключения

Схема подключения компонентов

Для подключения мы используем интерфейс I2C. Это стандарт для OLED-дисплеев, который требует всего два сигнальных провода, помимо питания.

Важно: В коде мы будем использовать внутреннюю подтяжку пина кнопки (INPUT_PULLUP), поэтому дополнительный резистор на кнопку ставить не обязательно — просто подключаем её напрямую между пином 15 и землей (GND).

КомпонентПин дисплея / кнопкиПин ESP32 (GPIO)Описание
OLED DisplayVCC3.3VПитание дисплея
OLED DisplayGNDGNDОбщий минус
OLED DisplaySCLGPIO 22Тактовая линия I2C
OLED DisplaySDAGPIO 21Линия данных I2C
КнопкаPin 1GPIO 15Сигнал прыжка
КнопкаPin 2GNDЗамыкание на землю

Симуляция в Wokwi: Тестируем без железа

Перед тем как брать в руки паяльник, я рекомендую проверить всё в онлайн-симуляторе. Это сэкономит время на отладку.

Попробовать игру в браузере:

Разбор программной части

Для работы экрана нам понадобятся проверенные инструменты от Adafruit. Вы можете установить их через «Менеджер библиотек» в Arduino IDE или скачать напрямую с GitHub:

  • Adafruit SSD1306 — основной драйвер для нашего дисплея.
  • Adafruit GFX Library — графическое ядро, которое отвечает за отрисовку линий, пикселей и шрифтов.
  • Adafruit BusIO(Важно!) техническая библиотека, обеспечивающая связь между ESP32 и дисплеем по шине I2C.

Совет: При установке через менеджер библиотек Arduino IDE предложит установить все зависимости (dependencies) — обязательно соглашайтесь, чтобы не скачивать каждый компонент вручную. Adafruit BusIO эта библиотека загрузится автоматически

Логика игрового цикла

Программа для ESP32 состоит из двух основных фаз: подготовки (setup) и бесконечного повторения (loop). В играх это называется «игровым движком».

Функция loop() — Игровой цикл

Здесь мы «будим» железо. Программа выполняется один раз при включении питания:

  • Запуск дисплея: Проверка, видит ли ESP32 наш OLED через I2C.
  • Настройка кнопки: Установка пина 15 в режим INPUT_PULLUP (внутренняя подтяжка к питанию), чтобы кнопка не срабатывала от помех.
  • Загрузка графики: Отрисовка начального экрана с надписью «Press to Start».

Функция setup() — Инициализация

Это сердце игры. Цикл повторяется десятки раз в секунду, создавая иллюзию движения:

  • Чтение ввода: Проверяем, нажата ли кнопка. Если да — запускаем функцию прыжка.
  • Обновление координат: Пересчитываем положение кактусов и динозавра (физика гравитации).
  • Проверка столкновений: Если координаты динозавра совпали с координатами кактуса — игра останавливается.
  • Отрисовка кадра: Очищаем старую картинку и рисуем объекты на новых местах.

Физика прыжка (Пример кода) Dino Run на ESP32

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

void updateDino() {
  if (isJumping) {
    velocity += gravity; // Гравитация тянет вниз
    dinoY += velocity;   // Изменяем высоту

    // Проверка приземления
    if (dinoY >= groundLevel) {
      dinoY = groundLevel;
      isJumping = false;
    }
  }
}

Вход

Нажатие кнопки (GPIO 15).

Обработка

Расчет физики и логики игры.

Выход

Отрисовка кадра на OLED.

Код игры Dino Run на ESP32

#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

// Настройки дисплея
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_RESET -1
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

// Пины
const int buttonPin = 15;

// Физика игры
int dinoY = 45; // Высота динозавра
int velocity = 0; // Скорость прыжка
int gravity = 2; // Гравитация
bool isJumping = false;
int obstacleX = 128; // Позиция кактуса
int score = 0;

void setup() {
Serial.begin(115200);
pinMode(buttonPin, INPUT_PULLUP); // Кнопка с внутренней подтяжкой

if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
Serial.println(F("OLED не найден"));
for(;;);
}

display.clearDisplay();
display.setTextSize(1);
display.setTextColor(WHITE);
}

void loop() {
// 1. INPUT (Вход)
if (digitalRead(buttonPin) == LOW && !isJumping) {
velocity = -12; // Импульс прыжка вверх
isJumping = true;
}

// 2. PROCESS (Обработка)
// Логика прыжка
if (isJumping) {
dinoY += velocity;
velocity += gravity;
if (dinoY >= 45) {
dinoY = 45;
isJumping = false;
}
}

// Движение кактуса
obstacleX -= 6;
if (obstacleX < -10) {
obstacleX = 128;
score++;
}

// Проверка столкновения (упрощенная)
if (obstacleX > 15 && obstacleX < 25 && dinoY > 35) {
gameOver();
}

// 3. OUTPUT (Выход)
drawGame();
delay(30); // Ограничение FPS
}

void drawGame() {
display.clearDisplay();

// Рисуем землю
display.drawLine(0, 55, 128, 55, WHITE);

// Рисуем Динозавра (квадратик для простоты в 1 части)
display.fillRect(20, dinoY, 10, 10, WHITE);

// Рисуем кактус
display.fillRect(obstacleX, 45, 6, 10, WHITE);

// Рисуем счет
display.setCursor(0,0);
display.print("Score: ");
display.print(score);

display.display();
}

void gameOver() {
display.clearDisplay();
display.setCursor(30, 25);
display.setTextSize(2);
display.print("GAME OVER");
display.display();
delay(2000);
score = 0;
obstacleX = 128;
}
Dino Run на ESP32

AndiBond.com


Поддержите проект AndiBond

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

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

Каждый донат — это топливо для новых статей и видео. Спасибо, что вы со мной!»

Один комментарий

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

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

Build Your Own Retro Game Console with ESP32

Most makers have a spare ESP32 and a 0.96″ OLED display lying around. Today, we’ll put that hardware to use by porting the legendary Chrome game. In this ESP32 Dino Run tutorial, we’ll cover the wiring, game loop logic, and basic jump physics.

No hardware? Test the ESP32 Dino Run code instantly in the Wokwi online simulator.

Hardware and Wiring Schematic

We use the I2C interface for this ESP32 Dino Run engineering project, which keeps the wiring simple with only two signal lines.

Components List:

  • ESP32 DevKit V1
  • OLED 0.96″ (SSD1306)
  • Tactile Switch (Button)
  • Breadboard
  • Jumper Wires

Pinout Configuration

For the ESP32 Dino Run project, we use the standard I2C pins. We also use the internal INPUT_PULLUP resistor for the jump button.

We use the internal INPUT_PULLUP resistor. Connect the button directly between GPIO 15 and GND.

ComponentDisplay / Button PinESP32 Pin (GPIO)Description
OLED DisplayVCC3.3VDisplay Power
OLED DisplayGNDGNDCommon Ground (GND)
OLED DisplaySCLGPIO 22I2C Clock Line
OLED DisplaySDAGPIO 21I2C Data Line
ButtonPin 1GPIO 15Jump Signal
ButtonPin 2GNDConnect to GND

Wokwi Simulation: Testing Without Hardware

Before picking up your soldering iron, I recommend testing everything in an online simulator. This will save you significant debugging time.

Try the game in your browser:

Open in Wokwi

Software and Libraries

To run the ESP32 Dino Run game, you will need the Adafruit libraries. Install them via the Library Manager in the Arduino IDE:

  • Adafruit SSD1306 — the main driver for our display.
  • Adafruit GFX Library — the graphics core responsible for rendering lines, pixels, and fonts.
  • Adafruit BusIO(Important!) a technical library that enables I2C communication between the ESP32 and the display.

Pro Tip: When installing via the Library Manager, the Arduino IDE will prompt you to install all dependencies. Make sure to click «Install All» to avoid downloading each component manually. This ensures that the Adafruit BusIO library is loaded automatically.

ESP32 Dino Run Game Logic

The program consists of two main phases: setup (initialization) and loop (infinite repetition). This structure forms the core of our ESP32 Dino Run engine.

The setup() Function — Initialization

This is where we «wake up» the hardware for our ESP32 Dino Run project:

  • Display Startup: Checking the I2C bus.
  • Button Setup: Setting GPIO 15 to pull-up mode.

The loop() Function — The Game Loop

The heart of the ESP32 Dino Run game. It repeats dozens of times per second:

  • Input Handling: Checking the jump button.
  • Processing: Recalculating physics (gravity and velocity).
  • Collision Detection: Checking if the Dino hits a cactus.
  • Output: Rendering the frame on the OLED.

ESP32 Dino Run Source Code

Below is the complete code to launch your game. Copy this into your Arduino IDE to start your ESP32 Dino Run adventure.

void updateDino() {
  if (isJumping) {
    velocity += gravity; // Gravity pulls down
    dinoY += velocity;   // Update vertical position

    // Check for landing
    if (dinoY >= groundLevel) {
      dinoY = groundLevel;
      isJumping = false;
    }
  }

Input

Button Press (GPIO 15)

Processing

Physics and Game Logic Calculations

Output

OLED Frame Rendering

Dino Run Game Code for ESP32

#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

// Display settings
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_RESET -1
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

// Pins
const int buttonPin = 15;

// Game physics
int dinoY = 45; // Dinosaur height
int velocity = 0; // Jump velocity
int gravity = 2; // Gravity
bool isJumping = false;
int obstacleX = 128; // Cactus position
int score = 0;

void setup() {
Serial.begin(115200);
pinMode(buttonPin, INPUT_PULLUP); // Button with internal pull-up

if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
Serial.println(F("OLED not found"));
for(;;);
}

display.clearDisplay();
display.setTextSize(1);
display.setTextColor(WHITE);
}

void loop() {
// 1. INPUT
if (digitalRead(buttonPin) == LOW && !isJumping) {
velocity = -12; // Upward jump impulse
isJumping = true;
}

// 2. PROCESS
// Jump logic
if (isJumping) {
dinoY += velocity;
velocity += gravity;
if (dinoY >= 45) {
dinoY = 45;
isJumping = false;
}
}

// Cactus movement
obstacleX -= 6;
if (obstacleX < -10) {
obstacleX = 128;
score++;
}

// Collision check (simplified)
if (obstacleX > 15 && obstacleX < 25 && dinoY > 35) {
gameOver();
}

// 3. OUTPUT
drawGame();
delay(30); // FPS limit
}

void drawGame() {
display.clearDisplay();

// Draw ground
display.drawLine(0, 55, 128, 55, WHITE);

// Draw Dinosaur (square for simplicity in part 1)
display.fillRect(20, dinoY, 10, 10, WHITE);

// Draw cactus
display.fillRect(obstacleX, 45, 6, 10, WHITE);

// Draw score
display.setCursor(0,0);
display.print("Score: ");
display.print(score);

display.display();
}

void gameOver() {
display.clearDisplay();
display.setCursor(30, 25);
display.setTextSize(2);
display.print("GAME OVER");
display.display();
delay(2000);
score = 0;
obstacleX = 128;
}
ESP32 Dino Run

AndiBond.com


Support the AndiBond project

Creating high-quality guides, finding working solutions, and debugging code takes a lot of time. All my projects remain open-source and free, so that everyone can enter the world of electronics with the lowest possible barrier to entry.

If this tutorial saved you time or helped you launch your first game on the ESP32, you can support the blog’s development. Your support helps me purchase new sensors, displays, and controllers for future reviews and projects.

Support Project Development

Every donation is fuel for new articles and videos. Thank you for being with me!

2 комментария

  1. Hey There. I found your blog using msn. This is an extremely well written article. I’ll make sure to bookmark it and return to read more of your useful info. Thanks for the post. I will definitely comeback.

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

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