#include "snake_functions.h" void gamePlay(); // ================================================================== // ================================================================== // MAIN -> including game mechanics // ================================================================== void setup() { Serial.begin(9600); if (!display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS)) { Serial.println(F("SSD1306 allocation failed")); for (;;); delay(100); } display.setRotation(2); // <- rotate screen 180 degrees here setupButtons(); randomSeed(analogRead(0)); resetGame(false); } void loop() { gamePlay(); } // ================================================================== // whole gameplay void gamePlay() { if (digitalRead(BTN_RESTART) == LOW) { resetGame(true); delay(300); return; } if (digitalRead(BTN_PAUSE) == LOW && millis() - lastPauseTime > 500) // debounce the button press { paused = !paused; // Toggle the pause state lastPauseTime = millis(); // Record time of last button press } if (gameOver) { drawGameOver(); return; } if (paused) { display.clearDisplay(); display.setTextSize(2); display.setTextColor(SSD1306_WHITE); display.setCursor((SCREEN_WIDTH / 2) - 30, (SCREEN_HEIGHT / 2) - 8); display.print("PAUSED"); display.display(); return; // Skip the rest of the game logic if paused } // sterowanie if (digitalRead(BTN_UP) == LOW && dirY != 1) { dirX = 0; dirY = -1; } if (digitalRead(BTN_DOWN) == LOW && dirY != -1) { dirX = 0; dirY = 1; } if (digitalRead(BTN_LEFT) == LOW && dirX != 1) { dirX = -1; dirY = 0; } if (digitalRead(BTN_RIGHT) == LOW && dirX != -1) { dirX = 1; dirY = 0; } unsigned long now = millis(); if (now - lastMoveTime >= moveInterval) { lastMoveTime = now; Point newHead = {snake[0].x + dirX, snake[0].y + dirY}; // moving vector // ------------------------------------------ // COLLISIONS // wall collision if (newHead.x <= 0 || newHead.y <= 0 || newHead.x >= GRID_WIDTH - 1 || newHead.y >= GRID_HEIGHT - 1) { gameOver = true; return; } // snake self collision for (int i = 0; i < snakeLength; i++) { if (snake[i].x == newHead.x && snake[i].y == newHead.y) { gameOver = true; return; } } // ------------------------------------------ // MOVEMENT // snake move for (int i = snakeLength; i > 0; i--) { snake[i] = snake[i - 1]; } snake[0] = newHead; // food eating if ((newHead.x == food1.x && newHead.y == food1.y) || (newHead.x == food2.x && newHead.y == food2.y)) { score++; // Increment score when food is eaten if (snakeLength < SNAKE_MAX_LENGTH) { snakeLength += 3; moveInterval = max(40, moveInterval - 20); // Speed up } spawnFood(); // Spawn new food } else if (snakeLength > SNAKE_MAX_LENGTH) // dont go over array bounds { snakeLength = SNAKE_MAX_LENGTH; } // draw all drawGame(); } }