Projekt to gra Arkanoid stworzona na platformie Arduino Uno. Gra polega na odbijaniu piłki za pomocą platformy w celu zburzenia bloków na ekranie. Projekt ten jest świetnym sposobem na naukę programowania mikrokontrolerów oraz zabawę z elektroniką. Kod wygenerowano przy wsparciu technologii AI.
1. Płytka Arduino UNO
2. Game Console
3. Wyświetlacz
Gra Arkanoid na Arduino Uno
Gra Arkanoid na Arduino Uno to ekscytujący projekt, który łączy w sobie pasję do programowania mikrokontrolerów z klasyczną grą zręcznościową. Arkanoid, znany także jako "Breakout", to kultowa gra, w której gracz steruje platformą, próbując odbić piłeczkę tak, aby zburzyć wszystkie bloki na planszy. Ten projekt przenosi tę klasyczną rozrywkę na platformę Arduino Uno, oferując nie tylko wspaniałą zabawę, ale również edukacyjne doświadczenie w dziedzinie programowania i elektroniki.
Zasada działania:
Podstawowym elementem projektu jest Arduino Uno, popularny mikrokontroler łatwy w użyciu i dostępny dla hobbystów oraz studentów. Do sterowania grą wykorzystuje się przyciski, które odpowiadają za ruch platformy w lewo i w prawo. Wyświetlacz pełni rolę ekranu, na którym wyświetlane są bloki oraz piłka.
Opis menu:
W grze jest dostępne menu w którym można wybrać szybkość platformy, poziomy trudności gry, które zwiększają prędkość piłki.
Sterowanie:
Sterowanie platformą odbywa się za pomocą dwóch przycisków po prawej stronie konsoli, a za sterowanie menu odpowiadają cztery przyciski z lewej strony konsoli. Aby rozpocząć grę należy wcisnąć spośród czterech przycisków po lewej stronie ten prawy.
#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);
const int buttonLeftPin = 5;
const int buttonRightPin = 4;
const int menuUpPin = 7;
const int menuDownPin = 9;
const int selectButtonPin = 8;
const int decreaseSpeedPin = 10; // Pin do zmniejszania prędkości paletki i poziomu trudności
int paddleWidth = 24;
int paddleHeight = 4;
int paddleX;
int paddleSpeed = 5; // Prędkość paletki
int ballSize = 4;
int ballX, ballY;
int ballVelocityX, ballVelocityY;
int score = 0;
int highScore = 0;
const int blocksRows = 4;
const int blocksCols = 8;
bool blocks[blocksRows][blocksCols];
const int blockWidth = SCREEN_WIDTH / blocksCols;
const int blockHeight = 6;
int menuState = 0; // 0: Start game, 1: Difficulty, 2: Paddle Speed
int difficultyLevel = 1; // 1: Easy, 2: Medium, 3: Hard
bool inGame = false;
void setup() {
pinMode(buttonLeftPin, INPUT_PULLUP);
pinMode(buttonRightPin, INPUT_PULLUP);
pinMode(menuUpPin, INPUT_PULLUP);
pinMode(menuDownPin, INPUT_PULLUP);
pinMode(selectButtonPin, INPUT_PULLUP);
pinMode(decreaseSpeedPin, INPUT_PULLUP);
display.begin(SSD1306_SWITCHCAPVCC, 0x3C); // Inicjalizacja wyświetlacza
display.clearDisplay();
display.setRotation(2); // Obrót ekranu o 180 stopni
display.display();
resetGame();
}
void resetGame() {
paddleX = (SCREEN_WIDTH - paddleWidth) / 2;
ballX = paddleX + paddleWidth / 2 - ballSize / 2;
ballY = SCREEN_HEIGHT - paddleHeight - ballSize - 5;
int speedModifier = difficultyLevel == 1 ? 1 : (difficultyLevel == 2 ? 2 : 3);
ballVelocityX = 2 * speedModifier;
ballVelocityY = -2 * speedModifier;
score = 0;
for (int i = 0; i < blocksRows; i++) {
for (int j = 0; j < blocksCols; j++) {
blocks[i][j] = true;
}
}
}
void drawBlocks() {
for (int i = 0; i < blocksRows; i++) {
for (int j = 0; j < blocksCols; j++) {
if (blocks[i][j]) {
display.fillRect(j * blockWidth, i * blockHeight + 20, blockWidth - 1, blockHeight - 1, WHITE);
}
}
}
}
void drawMenu() {
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(WHITE);
display.setCursor(0, 0);
if (menuState == 0) {
display.println(F("Start Game"));
} else if (menuState == 1) {
display.print(F("Difficulty: "));
switch (difficultyLevel) {
case 1: display.println(F("Easy")); break;
case 2: display.println(F("Medium")); break;
case 3: display.println(F("Hard")); break;
}
} else if (menuState == 2) {
display.print(F("Paddle Speed: "));
display.println(paddleSpeed);
}
display.display();
}
void handleMenuInput() {
static unsigned long lastPressTime = 0;
unsigned long currentTime = millis();
if (currentTime - lastPressTime < 200) return; // Debouncing
if (digitalRead(selectButtonPin) == LOW) {
lastPressTime = currentTime;
if (menuState ==0){
inGame = true; // Rozpoczęcie gry
resetGame();
} else if (menuState == 1) {
difficultyLevel = (difficultyLevel % 3) + 1; // Zmiana poziomu trudności
} else if (menuState == 2) {
paddleSpeed = paddleSpeed >= 10 ? 10 : paddleSpeed + 1; // Zwiększanie prędkości paletki
}
}
if (digitalRead(decreaseSpeedPin) == LOW) {
lastPressTime = currentTime;
if (menuState == 1) { // Zmniejszanie poziomu trudności
difficultyLevel--;
if (difficultyLevel < 1) difficultyLevel = 3; // Cykliczne przewijanie
} else if (menuState == 2) { // Zmniejszanie prędkości paletki
paddleSpeed = paddleSpeed <= 1 ? 1 : paddleSpeed - 1;
}
}
if (digitalRead(menuUpPin) == LOW) {
lastPressTime = currentTime;
menuState--;
if (menuState < 0) menuState = 2; // Cykliczne przewijanie w górę
}
if (digitalRead(menuDownPin) == LOW) {
lastPressTime = currentTime;
menuState++;
if (menuState > 2) menuState = 0; // Cykliczne przewijanie w dół
}
}
void updateGame() {
if (!digitalRead(buttonLeftPin) && paddleX > 0) {
paddleX -= paddleSpeed;
}
if (!digitalRead(buttonRightPin) && paddleX < SCREEN_WIDTH - paddleWidth) {
paddleX += paddleSpeed;
}
ballX += ballVelocityX;
ballY += ballVelocityY;
if (ballX <= 0 || ballX + ballSize >= SCREEN_WIDTH) {
ballVelocityX = -ballVelocityX;
}
if (ballY <= 0) {
ballVelocityY = -ballVelocityY;
} else if (ballY + ballSize >= SCREEN_HEIGHT) {
inGame = false; // Koniec gry, piłka spadła
display.clearDisplay();
display.setTextSize(2);
display.setCursor(20, 20);
display.print("Game Over");
display.setTextSize(1);
display.setCursor(5, 50);
display.print("Score: ");
display.print(score);
display.display();
delay(3000); // Wyświetl ekran końcowy przez 3 sekundy
}
if (ballX < paddleX + paddleWidth && ballX + ballSize > paddleX && ballY + ballSize > SCREEN_HEIGHT - paddleHeight) {
ballVelocityY = -ballVelocityY; // Odbicie od paletki
}
for (int i = 0; i < blocksRows; i++) {
for (int j = 0; j < blocksCols; j++) {
if (blocks[i][j] && ballX + ballSize > j * blockWidth && ballX < j * blockWidth + blockWidth
&& ballY + ballSize > i * blockHeight + 20 && ballY < i * blockHeight + 20 + blockHeight) {
blocks[i][j] = false;
ballVelocityY = -ballVelocityY;
score += 10;
break;
}
}
}
}
void drawGame() {
display.clearDisplay();
drawBlocks();
display.fillRect(paddleX, SCREEN_HEIGHT - paddleHeight, paddleWidth, paddleHeight, WHITE);
display.fillCircle(ballX, ballY, ballSize / 2, WHITE);
display.setTextSize(1);
display.setCursor(0, 0);
display.print("Score: ");
display.print(score);
display.display();
}
void loop() {
if (inGame) {
updateGame();
drawGame();
} else {
handleMenuInput();
drawMenu();
}
}