Skip to content

Instantly share code, notes, and snippets.

@KylePiira
Last active October 4, 2019 05:51
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save KylePiira/300fe2b344e8093c0be90187e21f6dad to your computer and use it in GitHub Desktop.
A Pong implementation for the UMass CICS 290M Makerboard
// Imports
#include <Adafruit_SSD1306.h>
// Globals
#define UP_BUTTON 34
#define DOWN_BUTTON 0
#define RESET_BUTTON 35
#define BUZZER 17
// Game State
int score = 0;
// Paddle
int paddle_pos = 32;
int paddle_velocity = 1;
int paddle_height = 16;
int paddle_width = 4;
// Ball
volatile int ball_x = random(10, 80);
volatile int ball_y = random(16, 48);
volatile int ball_radius = 3;
volatile int ball_velocity_x = random(1, 3);
volatile int ball_velocity_y = random(1, 3);
Adafruit_SSD1306 lcd(128, 64); // create display object
// Callbacks
void IRAM_ATTR moveUp() {
if (paddle_pos >= 0) {
paddle_pos -= 1;
}
}
void IRAM_ATTR moveDown() {
if (paddle_pos + paddle_height <= 64) {
paddle_pos += 1;
}
}
void IRAM_ATTR restart() {
if (gameOver()) {
score = 0;
ball_x = random(10, 80);
ball_y = random(16, 48);
ball_velocity_x = random(1, 3);
ball_velocity_y = random(1, 3);
}
}
void setup() {
Serial.begin(9600);
pinMode(BUZZER, OUTPUT);
pinMode(UP_BUTTON, INPUT);
pinMode(DOWN_BUTTON, INPUT);
pinMode(RESET_BUTTON, INPUT);
lcd.begin(SSD1306_SWITCHCAPVCC, 0x3C); // init
lcd.setTextColor(WHITE);
lcd.clearDisplay(); // clear software buffer
lcd.display();
attachInterrupt(RESET_BUTTON, restart, FALLING);
}
// Test if coordinates are out of bounds
boolean yIsOutOfBounds(int y) {return y > 63 || y < 0;}
boolean xIsOutOfBounds(int x) {return x > 127 || x < 0;}
boolean outOfBounds(int x, int y) {return xIsOutOfBounds(x) || yIsOutOfBounds(y);}
boolean gameOver() {return ball_x + ball_radius >= 127;}
boolean ballPaddleCollision(int x, int y) {
return (x > 128 - paddle_width) && (y < paddle_pos + paddle_height && y > paddle_pos);
}
void drawPaddle(int x, int y, int width, int height) {
lcd.fillRect(x, y, width, height, WHITE);
}
void ding() {
ledcSetup(0, 5000, 8);
ledcAttachPin(BUZZER, 0);
ledcWriteTone(0, 500);
delay(50); // 500Hz for 0.05 second
ledcWriteTone(0, 0); // buzzer off
}
void drawBall() {
lcd.fillCircle(ball_x, ball_y, ball_radius, BLACK);
if (xIsOutOfBounds(ball_x + ball_radius) || xIsOutOfBounds(ball_x - ball_radius)) {
ball_velocity_x *= -1;
ding();
}
if (yIsOutOfBounds(ball_y + ball_radius) || yIsOutOfBounds(ball_y - ball_radius)) {ball_velocity_y *= -1;}
if (ballPaddleCollision(ball_x + ball_radius, ball_y) || ballPaddleCollision(ball_x - ball_radius, ball_y)) {
ball_velocity_x *= -1;
ding();
score++;
}
ball_x += ball_velocity_x;
ball_y += ball_velocity_y;
lcd.fillCircle(ball_x, ball_y, ball_radius, WHITE);
}
void loop() {
// Check if Game is over
if (gameOver()) {
lcd.clearDisplay();
lcd.setCursor(0,0);
lcd.print("Score: " + String(score) + "\nPress bottom button \nto restart.");
lcd.display();
return;
}
// Check for button presses
if (!digitalRead(UP_BUTTON)) {
moveUp();
}
if (!digitalRead(DOWN_BUTTON)) {
moveDown();
}
lcd.clearDisplay();
drawPaddle(0, ball_y - (paddle_height / 2), paddle_width, paddle_height);
drawPaddle(127 - paddle_width, paddle_pos + paddle_velocity, paddle_width, paddle_height);
drawBall();
lcd.display();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment