The code above runs a basic LED pong game on two WS8212 strips of 5 LEDs each.
Created
September 25, 2021 05:12
-
-
Save ItsMichal/73bbc6190475ab6cd8c3e219c2e4cb9f to your computer and use it in GitHub Desktop.
LED Pong
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// LED Pong | |
// Michal Bodzianowski (c) 2021 | |
#include <Adafruit_NeoPixel.h> | |
// Fix for dropping inputs. Every tick, inputRatio | |
// number of inputs will be listend for. In this case, | |
// max delay is at 30ms. If you can click the button | |
// and release it faster than that... god bless you. | |
const int inputRatio = 10; | |
int counter = 0; | |
// Pins for LED strips and controls | |
const int buttonPin =11; | |
const int switchPin = 9; | |
const int neoPinOne = 4; | |
const int neoPinTwo = 3; | |
//Led params | |
const int ledWidth = 5; //Fully implemented | |
const int ledHeight = 2; //Only works as two for now. | |
//Initialize LED strips | |
Adafruit_NeoPixel neoOne(ledWidth, neoPinOne, NEO_GRB + NEO_KHZ800); | |
Adafruit_NeoPixel neoTwo(ledWidth, neoPinTwo, NEO_GRB + NEO_KHZ800); | |
//Game parameters | |
int pongBallX = 1; //X pos of the pongball | |
int pongBallY = 0; //Y pos of the pongball | |
int pongDir = -1; //Direciton | |
int comY = 0; // Position of the computer | |
int playerY = 0; //Position of the player | |
bool startedPong = false; // Whether the game has started (unused for now) | |
int delayGame = 300; // Delay to start the game at. Eventually gets lower and lower. | |
bool buttonPress = false; // Whether the button is being pressed. Prevents state from switching too often | |
// Setup | |
void setup() | |
{ | |
//Start pins and strips | |
pinMode(buttonPin, INPUT); | |
pinMode(switchPin, INPUT); | |
neoOne.begin(); | |
neoTwo.begin(); | |
} | |
// Resets the game parameters | |
void resetGame(){ | |
playerY = 0; | |
pongBallX = 1; | |
pongBallY = 0; | |
pongDir = -1; | |
comY = 0; | |
playerY = 0; | |
startedPong = false; | |
delayGame = 300; | |
} | |
// Main Loop | |
void loop() | |
{ | |
//On button press- switch Player pos | |
if(digitalRead(buttonPin) == HIGH && buttonPress == false){ | |
buttonPress = true; | |
playerY++; | |
if(playerY > (ledHeight-1)){ | |
playerY =0; | |
} | |
}else if (digitalRead(buttonPin) == LOW){ //Prevents double input until button released | |
buttonPress= false; | |
} | |
// If game loop is set to go | |
// This allows player input to happen every 30ms | |
// without speeding up the game that much | |
if(inputRatio==counter){ | |
counter = 0; // Resets the counter | |
//Throw pong | |
pongBallX = pongBallX+pongDir; | |
//Player side | |
if(pongBallX == 0){ | |
//Hit player | |
if(pongBallY == playerY){ | |
// Randomly move ball up or down | |
if(random(0,2) == 1){ | |
pongBallY +=1; | |
} | |
pongDir = 1; // Switch dir | |
pongBallX = pongBallX+pongDir; // Move pongball | |
delayGame -= 10; // Speed up game | |
}else{ | |
// Miss player and lose game | |
for(int i = 0; i < ledWidth; i++){ | |
neoOne.setPixelColor(i, neoOne.Color(100,0,0)); | |
neoTwo.setPixelColor(i, neoOne.Color(100,0,0)); | |
} | |
neoOne.show(); | |
neoTwo.show(); | |
delay(3000); | |
resetGame(); | |
} | |
} | |
//COM side | |
if(pongBallX == ledWidth-1){ | |
//Return ball with random dir | |
//and speed up game | |
if(random(0,2) == 1){ | |
pongBallY +=1; | |
} | |
pongDir = -1; | |
pongBallX = pongBallX+pongDir; | |
delayGame -= 10; | |
} | |
//Enforce bounds. This code line | |
//prevents multiple lines unfortunately. | |
if(pongBallY > 1){ | |
pongBallY = 0; | |
} | |
//Set computer to pongball | |
//so it never "loses" | |
comY = pongBallY; | |
} | |
//Clear screen | |
for(int i = 0; i < ledWidth; i++){ | |
neoOne.setPixelColor(i, neoOne.Color(0,0,0)); | |
neoTwo.setPixelColor(i, neoOne.Color(0,0,0)); | |
} | |
//Display player | |
float div = (float) counter/ (float) inputRatio; | |
int brightness = 50; | |
//Set color of player | |
int color = neoOne.Color(100,100,100); | |
//Cheat code | |
//If switch is up, change player color | |
//to green and set player pos to ball pos | |
//so player never loses. | |
if(digitalRead(switchPin) == HIGH){ | |
color = neoOne.Color(0,100,0); | |
playerY = pongBallY; | |
} | |
//Set player LED on right strip | |
// This code also limits height | |
// as well as the next few blocks | |
if(playerY == 0){ | |
neoOne.setPixelColor(0, color); | |
}else{ | |
neoTwo.setPixelColor(0, color); | |
} | |
//Show computer LED | |
if(comY == 0){ | |
neoOne.setPixelColor(ledWidth-1, neoOne.Color(100,100,100)); | |
}else{ | |
neoTwo.setPixelColor(ledWidth-1, neoOne.Color(100,100,100)); | |
} | |
//Show pong ball LED | |
if(pongBallY == 0){ | |
neoOne.setPixelColor(pongBallX, neoOne.Color(0,0,brightness)); | |
//Set trailing LED | |
if(pongBallX-pongDir > 0 && pongBallX-pongDir < ledWidth-1){ | |
neoOne.setPixelColor(pongBallX-pongDir, neoOne.Color(0,0,brightness/2)); | |
} | |
}else{ | |
neoTwo.setPixelColor(pongBallX, neoTwo.Color(0,0,brightness)); | |
//Set trailing LED | |
if(pongBallX-pongDir > 0 && pongBallX-pongDir < ledWidth-1){ | |
neoTwo.setPixelColor(pongBallX-pongDir, neoTwo.Color(0,0,brightness/5)); | |
} | |
} | |
//Win condition | |
//If pongBall reaches 50ms delay then player has won. | |
if(delayGame < 50){ | |
//Light up green for 3s | |
for(int i = 0; i < ledWidth; i++){ | |
neoOne.setPixelColor(i, neoOne.Color(0,100,0)); | |
neoTwo.setPixelColor(i, neoOne.Color(0,100,0)); | |
} | |
neoOne.show(); | |
neoTwo.show(); | |
delay(3000); | |
// Reset the game | |
resetGame(); | |
} | |
//Show all LEDs | |
neoTwo.show(); | |
neoOne.show(); | |
//Set global delay- | |
//This is divided by inputRatio | |
//to allow for higher player input | |
//polling. Counter keeps track of | |
//when game logic should run. | |
//Default is every 10 input polls and 300ms. | |
delay(delayGame/inputRatio); | |
counter++; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment