Typ_projektu
Arduino
Zdjecie główne
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