Files
arduino_pong/arduino_pong.ino

133 lines
3.3 KiB
Arduino
Raw Normal View History

#include "Arduino_LED_Matrix.h"
2026-03-15 21:14:04 +01:00
#include "src/config.h"
#include "src/pong_render.h"
2026-03-17 23:25:30 +01:00
#include "src/paddle.h"
#include "src/ball.h"
#include "src/engine.h"
// create LED matrix object
ArduinoLEDMatrix matrix;
2026-03-15 20:29:56 +01:00
// initial pong frame matrix
2026-03-15 17:07:03 +01:00
byte frame[MATRIX_HEIGHT][MATRIX_WIDTH] = {
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
2026-03-15 20:29:56 +01:00
{ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
};
int need_refresh= true;
2026-03-17 23:25:30 +01:00
uint8_t ball_delay= INITIAL_BALL_DELAY;
long exec_t2= millis();
enum game_statuses : uint8_t {
TIMER,
RUN,
SCORE,
GAMEOVER,
WAIT,
};
game_statuses game_status= TIMER;
2026-03-17 23:25:30 +01:00
Ball ball(4, 6);
Paddle p1(1);
Paddle p2(4);
Engine engine(p1, p2, ball);
2026-03-15 20:29:56 +01:00
void setup() {
Serial.begin(9600);
2026-03-15 20:29:56 +01:00
// start LED matrix
matrix.begin();
pinMode(P1_BTN_UP, INPUT_PULLUP);
pinMode(P1_BTN_BOTTOM, INPUT_PULLUP);
pinMode(P2_BTN_UP, INPUT_PULLUP);
pinMode(P2_BTN_BOTTOM, INPUT_PULLUP);
2026-03-15 20:29:56 +01:00
randomSeed(millis());
}
void loop() {
long exec_t1= millis();
switch (game_status) {
2026-03-17 23:25:30 +01:00
case TIMER:
for (int i = START_TIMER; i >= 0; i--) {
render_timer(frame, i);
delay(1000);
matrix.renderBitmap(frame, MATRIX_HEIGHT, MATRIX_WIDTH);
}
game_status= RUN;
// delay the first ball movement
exec_t2= millis() + FIRST_START_BALL_DELAY;
break;
case RUN:
2026-03-17 23:25:30 +01:00
if (digitalRead(P1_BTN_UP) == LOW) {
p1.move_pad_up();
need_refresh= true;
}
else if (digitalRead(P1_BTN_BOTTOM) == LOW) {
p1.move_pad_down();
need_refresh= true;
}
if (digitalRead(P2_BTN_UP) == LOW) {
p2.move_pad_up();
need_refresh= true;
}
else if (digitalRead(P2_BTN_BOTTOM) == LOW) {
p2.move_pad_down();
need_refresh= true;
}
if (exec_t1 - exec_t2 > ball_delay) {
2026-03-17 23:25:30 +01:00
engine.run(ball_delay);
need_refresh= true;
2026-03-17 23:25:30 +01:00
if (engine.get_event() == P1SCORE || engine.get_event() == P2SCORE) {
game_status= SCORE;
// delay the ball movement after score
2026-03-17 23:25:30 +01:00
exec_t2= millis() + FIRST_START_BALL_DELAY + 1000;
} else exec_t2= exec_t1;
}
// rerender matrix only if something is changed
if (need_refresh) {
2026-03-17 23:25:30 +01:00
render_matrix(frame, p1, p2, ball);
matrix.renderBitmap(frame, MATRIX_HEIGHT, MATRIX_WIDTH);
2026-03-17 23:25:30 +01:00
need_refresh= false;
}
delay(50);
break;
case SCORE:
2026-03-17 23:25:30 +01:00
render_score(frame, p1, p2);
matrix.renderBitmap(frame, MATRIX_HEIGHT, MATRIX_WIDTH);
delay(1000);
2026-03-17 23:25:30 +01:00
if (p1.get_score() >= MAX_POINTS || p2.get_score() >= MAX_POINTS) {
game_status= GAMEOVER;
}
else game_status= RUN;
break;
case GAMEOVER:
2026-03-17 23:25:30 +01:00
render_winner(frame, matrix, p1, p2);
game_status= WAIT;
break;
case WAIT:
// keep showing the winner waiting for a restart
// restart game once one button is pressed
if (digitalRead(P1_BTN_UP) == LOW || digitalRead(P1_BTN_BOTTOM) == LOW || digitalRead(P2_BTN_UP) == LOW || digitalRead(P2_BTN_BOTTOM) == LOW) {
game_status= TIMER;
2026-03-17 23:25:30 +01:00
engine.reset();
}
delay(100);
break;
}
2026-03-14 21:35:19 +01:00
}