"Pacman"

Typ_projektu
Arduino
Zdjecie główne
Gra wzorowana na hitowej grze z lat '80 'Pac-man'
Krótki opis projektu

Gra wzorowana na hitowej grze z lat '80 'Pac-man'

Niezbędne elementy

 

1. Płytka Arduino UNO

2. 4 przyciski

3. Ekran OLED 128x64

Opis projektu

W grze poruszamy się pacman'em, w postaci kwadracika wyświetlany na ekranie. Za pomocą czterech przycisków możemy poruszać postacią w górę i dół oraz lewo i prawo. Mapa złożona jest ze ścian, przez które nie można przechodzić postacią oraz 'pikseli', które po wejściu pacman'em w nie dodają 10 punktów do wyniku wyświetlanego na górze ekranu. Kod został napisany z pomocą ChatGPT3.5.

kod programu

#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define SCREEN_ADDRESS 0x3C //possible Address; 0x3D , 0x3C or others

#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64

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

#define OK 5
#define NOOK 4


Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);

int pacmanX, pacmanY;
int pacmanSpeed = 2;
int pacmanDirectionX = 0;
int pacmanDirectionY = 0;

// Wymiary labiryntu i pozycje ścian
#define WALL_THICKNESS 2
#define WALL_GAP 8
#define WALL_START_X 0
#define WALL_START_Y 10
#define NUM_WALLS 30

#define PACMAN_SIZE 5
#define PIXEL_SIZE 2
#define PIXEL_GAP 10
#define NUM_PIXELS 40

int pixelX[NUM_PIXELS] = {63, 4, 4, 4, 4, 4, 4, 4,11,11,18,18,26,26,34,34,41,41,49,49,56,56,18,18,18,18,18,56,56,56,56,56,26,34,41,26,34,41,41,41};
int pixelY[NUM_PIXELS] = {36,14,21,28,36,44,52,58,14,58,14,58,14,58,14,58,14,58,14,58,14,58,21,28,36,44,52,21,28,36,44,52,44,44,44,28,28,28,21,52};
bool pixelEaten[NUM_PIXELS*2] = {false};
int points = 0;

int wallX1[NUM_WALLS] = {0 ,0 ,61,61,0 ,61,61,52,52,52,46,46,9 ,9 ,14,9 ,23,23,23,23,23,36,23,23,23,36,23};
int wallX2[NUM_WALLS] = {61,0 ,61,63,61,61,63,52,46,46,46,46,14,9 ,14,14,46,46,23,36,23,36,36,36,23,36,36};
int wallY1[NUM_WALLS] = {10,10,10,31,63,42,42,19,19,54,19,39,19,19,19,54,34,39,34,19,19,19,24,49,49,49,54};
int wallY2[NUM_WALLS] = {10,63,31,31,63,63,42,54,19,54,34,54,19,54,54,54,34,39,39,19,24,24,24,49,54,54,54};

void setup() {
  display.setRotation(2);
  pinMode(BUTTON_UP, INPUT_PULLUP);
  pinMode(BUTTON_DOWN, INPUT_PULLUP);
  pinMode(BUTTON_LEFT, INPUT_PULLUP);
  pinMode(BUTTON_RIGHT, INPUT_PULLUP);

  display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
  display.display();
  delay(2000);
  display.clearDisplay();

  pacmanX = 2;
  pacmanY = 12;

  
}

void loop() {
  handleInput();
  movePacman();
  checkWallCollision();
  eatPixels();
  drawGame();
  delay(100);
}

void handleInput() {
  if (!digitalRead(BUTTON_UP)) {
    pacmanDirectionY = -1;
    pacmanDirectionX = 0;
  } else if (!digitalRead(BUTTON_DOWN)) {
    pacmanDirectionY = 1;
    pacmanDirectionX = 0;
  } else if (!digitalRead(BUTTON_LEFT)) {
    pacmanDirectionX = -1;
    pacmanDirectionY = 0;
  } else if (!digitalRead(BUTTON_RIGHT)) {
    pacmanDirectionX = 1;
    pacmanDirectionY = 0;
  }
}
void eatPixels() {
  for (int i = 0; i <=NUM_PIXELS; i++) {
    if (!pixelEaten[i] && pacmanX + PACMAN_SIZE  > pixelX[i] && pacmanX < pixelX[i] + PIXEL_SIZE &&
        pacmanY + PACMAN_SIZE  > pixelY[i] && pacmanY < pixelY[i] + PIXEL_SIZE) {
      // Pac-Man zjadł piksel
      pixelEaten[i] = true;
      points+=10;
    }  if(!pixelEaten[i+40] && pacmanX + PACMAN_SIZE > -pixelX[i]+126 && pacmanX < -pixelX[i]+126 + PIXEL_SIZE &&
        pacmanY + PACMAN_SIZE  > pixelY[i] && pacmanY < pixelY[i] + PIXEL_SIZE){
          pixelEaten[i+40] = true;
          points+=10;
        }
  }
}
void movePacman() {
  pacmanX += pacmanSpeed * pacmanDirectionX;
  pacmanY += pacmanSpeed * pacmanDirectionY;

  if (pacmanX < 0) {
    pacmanX = 0;
  } else if (pacmanX + PACMAN_SIZE > SCREEN_WIDTH) {
    pacmanX = SCREEN_WIDTH - PACMAN_SIZE;
  }

  if (pacmanY < 0) {
    pacmanY = 0;
  } else if (pacmanY + PACMAN_SIZE > SCREEN_HEIGHT) {
    pacmanY = SCREEN_HEIGHT - PACMAN_SIZE;
  }
}
void checkWallCollision() {
  for (int i = 0; i < NUM_WALLS; i++) {
    if (pacmanX + PACMAN_SIZE >= wallX1[i] && pacmanX <= wallX2[i] + 1 &&
        pacmanY + PACMAN_SIZE >= wallY1[i] && pacmanY <= wallY2[i] + 1 ||
        pacmanX + PACMAN_SIZE >= -wallX2[i]+127 && pacmanX <= -wallX1[i] + 128 &&
        pacmanY + PACMAN_SIZE >= wallY1[i] && pacmanY <= wallY2[i]) {
      // Kolizja ze ścianą - zatrzymaj Pac-Mana
      pacmanX -= pacmanSpeed * pacmanDirectionX;
      pacmanY -= pacmanSpeed * pacmanDirectionY;
    }
  }
}

void drawGame() {
  display.clearDisplay();
  
  // Rysowanie ścian
  for (int i = 0; i < NUM_WALLS; i++) {
    display.drawLine(wallX1[i], wallY1[i], wallX2[i], wallY2[i], SSD1306_WHITE);
    display.drawLine(-wallX1[i]+127, wallY1[i], -wallX2[i]+127, wallY2[i], SSD1306_WHITE);
  }
 
  // Rysowanie pikseli
  for (int i = 2; i < NUM_PIXELS; i++) {
    if (!pixelEaten[i]) {
      display.fillRect(pixelX[i], pixelY[i], PIXEL_SIZE, PIXEL_SIZE, SSD1306_WHITE);
    }
    if (!pixelEaten[i+40])
      display.fillRect(-pixelX[i]+126, pixelY[i], PIXEL_SIZE, PIXEL_SIZE, SSD1306_WHITE);
   }
  if (!pixelEaten[0]) display.fillRect(pixelX[0], pixelY[0], PIXEL_SIZE, PIXEL_SIZE, SSD1306_WHITE);
  if (!pixelEaten[1]) display.fillRect(-pixelX[1]+126, pixelY[1], PIXEL_SIZE, PIXEL_SIZE, SSD1306_WHITE);
  // Rysowanie Pac-Mana
  display.fillRect(pacmanX, pacmanY, PACMAN_SIZE, PACMAN_SIZE, SSD1306_WHITE);
  
  // Wyświetlanie punktów na górze ekranu
  display.setTextSize(1);
  display.setTextColor(SSD1306_INVERSE);
  display.setCursor(SCREEN_WIDTH/2-6, 0);
  display.println(points);
  display.display();
}
Youtube
Tagi
arduino projekt gra pacman oled