#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);
// --- ПИКСЕЛЬНЫЕ СПРАЙТЫ 16x16 (как в настоящем GD) ---
// Кубик (16x16)
const unsigned char epd_bitmap_cube [] PROGMEM = {
0x00, 0x00, 0x00, 0x00, 0x03, 0xc0, 0x07, 0xe0, 0x0c, 0x30, 0x0b, 0xd0, 0x0b, 0xd0, 0x0c, 0x30,
0x0f, 0xf0, 0x0f, 0xf0, 0x0c, 0x30, 0x0f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
// Шип (16x16)
const unsigned char epd_bitmap_spike [] PROGMEM = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x80, 0x03, 0xc0, 0x07, 0xe0, 0x07, 0xe0,
0x0f, 0xf0, 0x0f, 0xf0, 0x1f, 0xf8, 0x1f, 0xf8, 0x3f, 0xfc, 0x3f, 0xfc, 0x7f, 0xfe, 0x7f, 0xfe
};
// --- ПИНЫ ---
const int BUTTON_PIN = 4;
const int BUZZER_PIN = 12;
// --- КОНСТАНТЫ ИГРЫ ---
const float GROUND_Y = 48.0; // Уровень земли (Y)
const float GRAVITY = 0.7; // Гравитация
const float JUMP_FORCE = -6.5; // Сила прыжка (минус = вверх)
const float SPIKE_SPEED = 4.0; // Скорость шипа
// --- ПЕРЕМЕННЫЕ КУБИКА ---
float cubeX = 10;
float cubeY = GROUND_Y;
float cubeVY = 0;
bool isJumping = false;
// --- ПЕРЕМЕННЫЕ ШИПА ---
float spikeX = 128;
float spikeY = GROUND_Y;
// --- СОСТОЯНИЯ ---
enum GameState { MENU, SELECT, PLAY };
GameState state = MENU;
bool gameOver = false;
unsigned long gameOverTime = 0;
const unsigned long RESPAWN_MS = 1000;
// --- АНТИДРЕБЕЗГ ---
bool lastReading = HIGH;
unsigned long lastDebounce = 0;
bool buttonStable = HIGH;
bool buttonPressedEdge = false;
// --- ЗВУК (как было) ---
// (вставь сюда свои массивы melodyFreq и melodyDuration из прошлого кода)
// ...
void setup() {
Serial.begin(9600);
pinMode(BUTTON_PIN, INPUT_PULLUP);
pinMode(BUZZER_PIN, OUTPUT);
// Инициализация OLED
if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
Serial.println(F("SSD1306 allocation failed"));
for(;;);
}
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(WHITE);
state = MENU;
}
void loop() {
// Чтение кнопки (антидребезг)
bool reading = digitalRead(BUTTON_PIN);
if (reading != lastReading) {
lastDebounce = millis();
lastReading = reading;
}
if ((millis() - lastDebounce) > 50) {
if (reading != buttonStable) {
buttonStable = reading;
if (buttonStable == LOW) buttonPressedEdge = true;
}
}
// --- ЛОГИКА СОСТОЯНИЙ ---
if (state == MENU) {
display.clearDisplay();
display.setCursor(20, 25);
display.print("GEOMETRY DASH");
display.display();
if (buttonPressedEdge) {
buttonPressedEdge = false;
state = SELECT;
}
return;
}
if (state == SELECT) {
display.clearDisplay();
display.setCursor(0, 20);
display.print("Choose level:");
display.setCursor(0, 35);
display.print("> Stereo Madness");
display.display();
if (buttonPressedEdge) {
buttonPressedEdge = false;
state = PLAY;
// Сброс координат
cubeY = GROUND_Y; cubeVY = 0; isJumping = false;
spikeX = 128;
gameOver = false;
}
return;
}
// --- ЛОГИКА ИГРЫ ---
if (gameOver) {
if (millis() - gameOverTime >= RESPAWN_MS) {
// Рестарт
cubeY = GROUND_Y; cubeVY = 0; isJumping = false;
spikeX = 128;
gameOver = false;
}
} else {
// Прыжок
if (buttonStable == LOW && !isJumping) {
cubeVY = JUMP_FORCE;
isJumping = true;
}
// Физика кубика
cubeVY += GRAVITY;
cubeY += cubeVY;
if (cubeY >= GROUND_Y) {
cubeY = GROUND_Y;
cubeVY = 0;
isJumping = false;
}
// Движение шипа
spikeX -= SPIKE_SPEED;
if (spikeX < -16) {
spikeX = 128; // Новый шип
}
// Коллизия (прямоугольники 16x16)
// Если кубик на земле и шип касается его по X
if (cubeY >= GROUND_Y - 2 && spikeX < cubeX + 16 && spikeX + 16 > cubeX) {
gameOver = true;
gameOverTime = millis();
// Тут можно вызвать startDeathSound()
}
}
// --- ОТРИСОВКА ---
display.clearDisplay();
// Рисуем землю (линия)
display.drawLine(0, GROUND_Y + 16, 128, GROUND_Y + 16, WHITE);
// Рисуем кубик (если не gameOver)
if (!gameOver) {
display.drawBitmap((int)cubeX, (int)cubeY, epd_bitmap_cube, 16, 16, WHITE);
display.drawBitmap((int)spikeX, (int)spikeY, epd_bitmap_spike, 16, 16, WHITE);
} else {
display.setCursor(40, 30);
display.print("GAME OVER");
}
display.display();
}Loading
ssd1306
ssd1306