This is an old revision of the document!
Proiectul implică dezvoltarea unui dispozitiv interactiv de divertisment, conceput pentru a oferi utilizatorilor o experiență de joc captivantă. Acest dispozitiv permite utilizatorilor să selecteze modul de joc (single player sau multiplayer) prin intermediul butoanelor disponibile, pentru un joc de Ping Pong. Apoi, ei interacționează cu joystick-urile dedicate pentru a participa la joc, care se desfășoară într-o serie de „best of 3”, afișându-se pe ecranul conectat. În funcție de rezultat, buzzer-ul va crea un sunet de învingător sau pierzător.
Scopul principal al dispozitivului este de a oferi o modalitate distractivă și interactivă de petrecere a timpului liber, aducând împreună elemente clasice de joc și tehnologie modernă.
Consider că acest joc nu are o utilitate mare în zona educației sau medicinei, dar conferă o notă de nostalgie jucătorilor care au avut primul contact cu un astfel de joc. Prin acest proiect încerc să dezvolt un joc vechi într-un mod cât mai plăcut pentru toată lumea.
Ideea de la care am pornit pentru acest proiect a fost una simplă: îmi doream să fac ceva „catchy”, dar suficient de complicat și interactiv.
1. Inițializarea joculu:
2. Începerea jocului
3. Procesarea mișcărilor
4. Încheierea jocului
5. Rematch
Lista componente:
Nume componentă | Cantitate |
---|---|
Arduino UNO (echivalent ATMega328P) | 1 |
Buzzer | 1 |
Joystick Analog | 2 |
Display LCD (I2C) | 1 |
Breadboard | 1 |
LED (diverse culori) | 1/2 |
Rezistor (diverse valori) | 1/2 |
Cabluri | nelimitat |
Modelul sistemului (cu componente vizibile):
Schematicul sistemului:
Pentru dezvoltarea acestui proiect, a fost utilizat mediu de dezvoltare Arduino IDE. Acesta oferă un mediu prietenos și ușor de utilizat pentru programarea microcontrolerelor din familia Atmega.
Au fost utilizate următoarele librării:
Algoritmii principali includ:
TODO
Codul sursă:
#include <Wire.h> #include <LiquidCrystal_I2C.h> const int SW_pin = 4; // digital pin connected to switch output const int player1 = A1; // analog pin connected to Y output const int player2 = A0; // analog pin connected to Y output const unsigned long PADDLE_RATE = 45; const unsigned long BALL_RATE = 0; const uint8_t PADDLE_HEIGHT = 12; int player1Score = 0; int player2Score = 0; int maxScore = 8; int BEEPER = 12; bool resetBall = false; #define SCREEN_WIDTH 16 // LCD display width, in characters #define SCREEN_HEIGHT 2 // LCD display height, in lines #define RESET_BUTTON 3 LiquidCrystal_I2C lcd(0x27, SCREEN_WIDTH, SCREEN_HEIGHT); // Set the LCD I2C address void drawCourt(); void drawScore(); uint8_t ball_x = 8, ball_y = 1; uint8_t ball_dir_x = 1, ball_dir_y = 1; unsigned long ball_update; unsigned long paddle_update; const uint8_t PLAYER2_X = 2; uint8_t player2_y = 0; const uint8_t PLAYER_X = 13; uint8_t player1_y = 0; void setup() { lcd.init(); lcd.backlight(); unsigned long start = millis(); pinMode(BEEPER, OUTPUT); pinMode(SW_pin, INPUT); pinMode(RESET_BUTTON, INPUT_PULLUP); digitalWrite(SW_pin, HIGH); lcd.clear(); drawCourt(); drawScore(); while (millis() - start < 2000); ball_update = millis(); paddle_update = ball_update; } void loop() { bool update = false; unsigned long time = millis(); static bool up_state = false; static bool down_state = false; if (resetBall) { if (player1Score == maxScore || player2Score == maxScore) { gameOver(); } else { lcd.clear(); drawScore(); drawCourt(); ball_x = random(7, 9); ball_y = random(0, 1); do { ball_dir_x = random(-1, 2); } while (ball_dir_x == 0); do { ball_dir_y = random(-1, 2); } while (ball_dir_y == 0); resetBall = false; } } if (time > ball_update) { uint8_t new_x = ball_x + ball_dir_x; uint8_t new_y = ball_y + ball_dir_y; // Check if we hit the vertical walls if (new_x == 0 || new_x == 15) { if (new_x == 0) { player1Score += 1; lcd.clear(); soundPoint(); resetBall = true; } else if (new_x == 15) { player2Score += 1; lcd.clear(); soundPoint(); resetBall = true; } ball_dir_x = -ball_dir_x; new_x += ball_dir_x + ball_dir_x; } // Check if we hit the horizontal walls. if (new_y == 0 || new_y == 1) { soundBounce(); ball_dir_y = -ball_dir_y; new_y += ball_dir_y + ball_dir_y; } // Check if we hit the player 2 paddle if (new_x == PLAYER2_X && new_y == player2_y) { soundBounce(); ball_dir_x = -ball_dir_x; new_x += ball_dir_x + ball_dir_x; } // Check if we hit the player 1 paddle if (new_x == PLAYER_X && new_y == player1_y) { soundBounce(); ball_dir_x = -ball_dir_x; new_x += ball_dir_x + ball_dir_x; } lcd.setCursor(ball_x, ball_y); lcd.print(" "); lcd.setCursor(new_x, new_y); lcd.print("O"); ball_x = new_x; ball_y = new_y; ball_update += BALL_RATE; update = true; } if (time > paddle_update) { paddle_update += PADDLE_RATE; // Player 2 paddle lcd.setCursor(PLAYER2_X, player2_y); lcd.print(" "); if (analogRead(player2) < 475) { player2_y = 0; } if (analogRead(player2) > 550) { player2_y = 1; } lcd.setCursor(PLAYER2_X, player2_y); lcd.print("|"); // Player 1 paddle lcd.setCursor(PLAYER_X, player1_y); lcd.print(" "); if (analogRead(player1) < 475) { player1_y = 0; } if (analogRead(player1) > 550) { player1_y = 1; } up_state = down_state = false; lcd.setCursor(PLAYER_X, player1_y); lcd.print("|"); } update = true; if (update) { drawScore(); if (digitalRead(SW_pin) == 0) // Player pressed button to stop the game { gameOver(); } } } // de implementat functiile
Elementul de noutate al proiectului este dat de posibilitatea de a interacționa direct cu sistemul prin intermediul joystickurilor.
TODO
Fişierele se încarcă pe wiki folosind facilitatea Add Images or other files. Namespace-ul în care se încarcă fişierele este de tipul :pm:prj20??:c? sau :pm:prj20??:c?:nume_student (dacă este cazul). Exemplu: Dumitru Alin, 331CC → :pm:prj2009:cc:dumitru_alin.