Maze Runner

Typ_projektu
Arduino
Zdjecie główne
Krótki opis projektu

Celem projektu było stworzenie prostej i łatwej w obsłudze gry w środowisku Arduino. Ten program, umożliwia zagranie w popularną grę Maze Runner. Założeniem gry jest dojście z pozcji początkowej do wyjścia unikając dotykania ścian. 

Niezbędne elementy

1. Płytka Arduino UNO

2. Wyświetlacz OLED 64x128 pikseli

3. "Game Console v0.2 beta"

4. Kabel USB do Arduino

Sprzęt

Komputer PC

Opis projektu

Opis projektu:

 

Projekt jest realizacją gry "Maze Runner", czyli w tłumaczeniu "Biegacz labiryntu". Gracz steruje postacią (pikselem), która porusza się po labiryncie, starając się dotrzeć do wyjścia. Labirynt jest przedstawiony na wyświetlaczu OLED, a gracz steruje postacią za pomocą przycisków sterujących.

 

Główne elementy projektu:

a) Konstrukcja

Wyświetlacz OLED: Do wyświetlania labiryntu i aktualnej pozycji gracza użyto wyświetlacza OLED o rozmiarach 128x64 pikseli.

Sterowanie: Gracz steruje postacią za pomocą czterech przycisków: góra, dół, lewo, prawo. Przyciski te odpowiadają za poruszanie postacią w odpowiednich kierunkach.

 

b) Interfejs

    Labirynt: Labirynt jest ręcznie zdefiniowany za pomocą białych linii na wyświetlaczu. ały ekran został obramowany, żeby wyjście z labiryntu było tylko jedno.

 

c) Gra

Zasady: Celem gry jest dotarcie od wejścia do labirytnu (lewy górny róg) aż do wyjścia (prawy dolny róg). Gracz musi unikać kolizji z liniami reprezentującymi ściany labiryntu.

Kolizje: Funkcja sprawdzająca kolizje zapobiega postaci przechodzenia przez ściany labiryntu. Jeśli postać ‘wejdzie’ w ścianę, jej ruch zostanie zatrzymany.

Wygrana: Gracz wygrywa, gdy dotrze do określonego punktu na planszy, który został zdefiniowany jako wyjście z labiryntu.

Przegrana: Jeśli postać gracza uderzy w ścianę, gra zostaje zakończona, a na ekranie OLED wyświetlany jest komunikat o zakończonej rozgrywce.

 

Projekt pozwala na prymitywną rozrywkę  oraz wykorzystuje podstawowe funkcje wyświetlacza OLED i obsługę przycisków. Dzięki temu, możliwe jest stworzenie prostej, lecz wciągającej gry.

kod programu

#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);

#define BUTTON_UP 9     
#define BUTTON_DOWN 7   
#define BUTTON_LEFT 8
#define BUTTON_RIGHT 10

int playerX = 2; // Pozycja gracza w osi X
int playerY = 2; // Pozycja gracza w osi Y

#define PLAYER_SIZE 1 // Rozmiar gracza

void setup() {
 pinMode(BUTTON_UP, INPUT_PULLUP);
 pinMode(BUTTON_DOWN, INPUT_PULLUP);
 pinMode(BUTTON_LEFT, INPUT_PULLUP);
 pinMode(BUTTON_RIGHT, INPUT_PULLUP);

 // Inicjalizacja wyświetlacza OLED
 if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
   Serial.println(F("Nie udało się znaleźć wyświetlacza OLED"));
   for(;;);
 }
 display.display();
 delay(1000); // Czekaj 2 sekundy przed rozpoczęciem gry
 display.clearDisplay();
 display.setTextSize(1);
 display.setTextColor(SSD1306_WHITE);
}

//  Ruch gracza
void loop() {
 // Sprawdzanie wciśniętych przycisków i przesuwanie gracza
 if (digitalRead(BUTTON_UP) == LOW && playerY > 0) {
   playerY -= 2;
 }
 if (digitalRead(BUTTON_DOWN) == LOW && playerY < SCREEN_HEIGHT - PLAYER_SIZE) {
   playerY += 2;
 }
 if (digitalRead(BUTTON_LEFT) == LOW && playerX > 0) {
   playerX -= 2;
 }
 if (digitalRead(BUTTON_RIGHT) == LOW && playerX < SCREEN_WIDTH - PLAYER_SIZE) {
   playerX += 2;
 }

//   Sprawdzenie kolizji z linią labiryntu
if (checkCollision(playerX, playerY)==true) {
  endGame(); // Zakończ grę, jeśli doszło do kolizji z linią
}

if (checkWin(playerX, playerY)==true) {
  win(); // Zakończ grę, jeśli jest wygrana
}
 // Rysowanie labiryntu
 display.clearDisplay();
 drawMaze();

 
 // Rysowanie gracza
display.fillRect(playerX, playerY, PLAYER_SIZE, PLAYER_SIZE, SSD1306_WHITE); // Wypełniony obszar gracza


 display.display();

 delay(100); // Opóźnienie dla płynnego ruchu gracza
}

 


void drawMaze() {
// Rysowanie ścianek labiryntu

// Rysowanie ścianek labiryntu
// Ramka
display.drawLine(6,0,SCREEN_WIDTH-1,0,SSD1306_WHITE);
display.drawLine(0,0,0,SCREEN_HEIGHT-2,SSD1306_WHITE);
display.drawLine(0,62,120,62,SSD1306_WHITE);
display.drawLine(127,0,127,62,SSD1306_WHITE);

// labirynt
 display.drawLine(6,0,6,24,SSD1306_WHITE);
 display.drawLine(6,24,18,24,SSD1306_WHITE);
 display.drawLine(18,24,18,6,SSD1306_WHITE);
 display.drawLine(18,6,34,6,SSD1306_WHITE);
 display.drawLine(12,0,12,18,SSD1306_WHITE);
 display.drawLine(40,6,40,44,SSD1306_WHITE);
 display.drawLine(0,30,24,30,SSD1306_WHITE);
 display.drawLine(18,30,18,44,SSD1306_WHITE);
 display.drawLine(18,44,34,44,SSD1306_WHITE);
 display.drawLine(24,30,24,12,SSD1306_WHITE);
 display.drawLine(6,36,6,46,SSD1306_WHITE);
 display.drawLine(6,36,18,36,SSD1306_WHITE);
 display.drawLine(24,12,34,12,SSD1306_WHITE);
 display.drawLine(30,18,40,18,SSD1306_WHITE);
 display.drawLine(46,0,46,34,SSD1306_WHITE);
 display.drawLine(46,34,40,34,SSD1306_WHITE);
 display.drawLine(41,56,6,56,SSD1306_WHITE);
 display.drawLine(24,24,34,24,SSD1306_WHITE);
 display.drawLine(24,30,34,30,SSD1306_WHITE);
 display.drawLine(12,50,12,41,SSD1306_WHITE);
 display.drawLine(24,44,24,49,SSD1306_WHITE);
 display.drawLine(18,50,18,56,SSD1306_WHITE);
 display.drawLine(6,56,6,61,SSD1306_WHITE);
 display.drawLine(120,61,120,50,SSD1306_WHITE); //1 
 display.drawLine(120,50,110,50,SSD1306_WHITE); //2
 display.drawLine(110,50,110,38,SSD1306_WHITE); //3
 display.drawLine(110,38,120,38,SSD1306_WHITE); //4  
 display.drawLine(116,44,125,44,SSD1306_WHITE); //5 
 display.drawLine(120,32,110,32,SSD1306_WHITE); //6 
 display.drawLine(41,56,41,61,SSD1306_WHITE);
 display.drawLine(31,50,52,50,SSD1306_WHITE);
 display.drawLine(58,61,58,50,SSD1306_WHITE);
 display.drawLine(34,44,34,36,SSD1306_WHITE);
 display.drawLine(46,24,66,24,SSD1306_WHITE);
 display.drawLine(46,40,46,50,SSD1306_WHITE);
 display.drawLine(46,40,52,40,SSD1306_WHITE);
 display.drawLine(52,30,52,40,SSD1306_WHITE);
 display.drawLine(52,30,72,30,SSD1306_WHITE);
 display.drawLine(72,18,72,30,SSD1306_WHITE);
 display.drawLine(72,18,72,30,SSD1306_WHITE);
 display.drawLine(52,18,72,18,SSD1306_WHITE);
 display.drawLine(52,18,52,6,SSD1306_WHITE);
 display.drawLine(58,12,58,6,SSD1306_WHITE);
 display.drawLine(80,6,86,6,SSD1306_WHITE);
 display.drawLine(58,12,74,12,SSD1306_WHITE);
 display.drawLine(46,12,52,12,SSD1306_WHITE);
 display.drawLine(64,0,64,6,SSD1306_WHITE);
 display.drawLine(70,6,76,6,SSD1306_WHITE);
 display.drawLine(0,50,12,50,SSD1306_WHITE);
 display.drawLine(58,36,58,38,SSD1306_WHITE);
 display.drawLine(58,50,70,50,SSD1306_WHITE);
 display.drawLine(70,50,70,44,SSD1306_WHITE);
 display.drawLine(76,56,76,41,SSD1306_WHITE);
 display.drawLine(76,56,58,56,SSD1306_WHITE);
 display.drawLine(58,56,58,61,SSD1306_WHITE);
 display.drawLine(52,61,52,56,SSD1306_WHITE);
 display.drawLine(58,56,58,43,SSD1306_WHITE);
 display.drawLine(58,56,58,38,SSD1306_WHITE);
 display.drawLine(70,44,64,44,SSD1306_WHITE);
 display.drawLine(83,56,98,56,SSD1306_WHITE);
 display.drawLine(98,56,98,44,SSD1306_WHITE);
 display.drawLine(110,32,110,18,SSD1306_WHITE); //7
 display.drawLine(110,18,120,18,SSD1306_WHITE); //8 
 display.drawLine(116,25,125,25,SSD1306_WHITE); //9
 display.drawLine(120,12,120,18,SSD1306_WHITE); //10
 display.drawLine(120,12,104,12,SSD1306_WHITE); //11     
 display.drawLine(104,18,104,61,SSD1306_WHITE); //12
 display.drawLine(120,6,104,6,SSD1306_WHITE); //13
 display.drawLine(104,12,104,0,SSD1306_WHITE); //14
 display.drawLine(104,18,98,18,SSD1306_WHITE); //15
 display.drawLine(98,18,98,6,SSD1306_WHITE); //16
 display.drawLine(98,6,86,6,SSD1306_WHITE); //17
 display.drawLine(74,6,80,6,SSD1306_WHITE); //18
 display.drawLine(80,6,80,12,SSD1306_WHITE); //19
 display.drawLine(80,12,74,12,SSD1306_WHITE); //20
 display.drawLine(86,12,92,12,SSD1306_WHITE); //21
 display.drawLine(92,12,92,18,SSD1306_WHITE); //22 
 display.drawLine(72,18,92,18,SSD1306_WHITE); //23
 display.drawLine(92,24,98,24,SSD1306_WHITE); //24
 display.drawLine(98,24,98,44,SSD1306_WHITE); //25
 display.drawLine(92,24,92,18,SSD1306_WHITE); //26
 display.drawLine(82,44,82,56,SSD1306_WHITE); //31
 display.drawLine(82,44,92,44,SSD1306_WHITE); //32
 display.drawLine(92,44,92,50,SSD1306_WHITE); //33
 display.drawLine(92,50,82,50,SSD1306_WHITE); //34
 display.drawLine(64,38,64,30,SSD1306_WHITE); //35
 display.drawLine(76,38,76,42,SSD1306_WHITE); //*
 display.drawLine(76,38,82,38,SSD1306_WHITE); //27
 display.drawLine(78,24,86,24,SSD1306_WHITE); //28
 display.drawLine(86,38,86,30,SSD1306_WHITE); //29
 display.drawLine(78,24,78,38,SSD1306_WHITE); //30
 display.drawLine(92,38,82,38,SSD1306_WHITE); //30*
 display.drawLine(82,44,82,56,SSD1306_WHITE); //31
 display.drawLine(82,44,92,44,SSD1306_WHITE); //32
 display.drawLine(92,44,92,50,SSD1306_WHITE); //33
 display.drawLine(92,50,82,50,SSD1306_WHITE); //34
 display.drawLine(92,30,86,30,SSD1306_WHITE); //40
 display.drawLine(92,30,92,38,SSD1306_WHITE); //41
 display.drawLine(78,24,86,24,SSD1306_WHITE); //42
 display.drawLine(86,38,82,38,SSD1306_WHITE); //30*

}

//  Wygrana
bool checkWin(int x, int y){

 if (x > 120 && y > 60) {
   return true;
 }
return false;
}


//  Sprawdzenie czy gracz dotknal scianki labiryntu
bool checkCollision(int x, int y) {
 
 // Sprawdzenie czy piksel obok gracza jest biały
 if (display.getPixel(x + 1, y) == SSD1306_WHITE ||
     display.getPixel(x - 1, y) == SSD1306_WHITE ||
     display.getPixel(x, y + 1) == SSD1306_WHITE ||
     display.getPixel(x, y - 1) == SSD1306_WHITE) {
   return true; // Kolizja
 }
 return false; // Brak kolizji
}

//  Koniec gry
void endGame() {
 // Wyświetlenie komunikatu na ekranie OLED
 display.clearDisplay();
 display.setTextSize(2);
 display.setTextColor(SSD1306_WHITE);
 display.setCursor(10, 20);
 display.println("  Koniec");
 display.println("    gry!");
 display.display();

 // Pętla nieskończona - zatrzymuje działanie programu
 while (true) {
   // Możesz tutaj dodać dodatkowe czynności po zakończeniu gry
 }
}

//   Wygrana
void win() {
 // Wyświetlenie komunikatu na ekranie OLED
 display.clearDisplay();
 display.setTextSize(2);
 display.setTextColor(SSD1306_WHITE);
 display.setCursor(10, 20);
 display.println("WYGRALES!");
 display.display();

 // Pętla nieskończona - zatrzymuje działanie programu

 while (true) {

   // Możesz tutaj dodać dodatkowe czynności po zakończeniu gry

 }

}

Youtube
Tagi
MazeRunner Labirynt gra ArduinoUNO Gameplay