#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
Adafruit_SSD1306 display(
SCREEN_WIDTH,
SCREEN_HEIGHT,
&Wire,
-1
);
//================ BUTTON =================
#define BTN_UP PB12
#define BTN_DOWN PB13
#define BTN_SELECT PB14
#define BTN_A PB15
#define BTN_B PA8
#define BTN_BACK PA9
#define BUZZER PA0
//================ STATE ==================
enum State {
MENU,
FLAPPY,
PINGPONG
};
State currentState = MENU;
int menuIndex = 0;
//================ FLAPPY =================
int birdY = 30;
int velocity = 0;
int pipeX = 128;
int gapY = 25;
int flappyScore = 0;
//================ PINGPONG ===============
int paddleY = 25;
int ballX = 64;
int ballY = 32;
int ballVX = 2;
int ballVY = 2;
int pongScore = 0;
//=========================================
bool pressed(int pin)
{
if (digitalRead(pin) == LOW)
{
delay(120);
return true;
}
return false;
}
//=========================================
void beep()
{
tone(BUZZER, 1200, 50);
}
//=========================================
void drawMenu()
{
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(WHITE);
display.setCursor(20, 5);
display.println("STM32 GAME");
display.setCursor(0, 25);
if(menuIndex==0) display.print(">");
display.print(" Flappy Bird");
display.setCursor(0, 40);
if(menuIndex==1) display.print(">");
display.print(" Ping Pong");
display.display();
}
//=========================================
void resetFlappy()
{
birdY = 30;
velocity = 0;
pipeX = 128;
gapY = random(15,45);
flappyScore = 0;
}
//=========================================
void runFlappy()
{
if(pressed(BTN_A))
{
velocity = -5;
beep();
}
velocity += 1;
birdY += velocity;
pipeX -= 3;
if(pipeX < -10)
{
pipeX = 128;
gapY = random(15,45);
flappyScore++;
beep();
}
if(birdY < 0 || birdY > 63)
{
resetFlappy();
}
if(pipeX < 20 && pipeX > 5)
{
if(birdY < gapY || birdY > gapY+20)
{
resetFlappy();
}
}
display.clearDisplay();
display.fillCircle(15,birdY,3,WHITE);
display.fillRect(pipeX,0,10,gapY,WHITE);
display.fillRect(pipeX,gapY+20,10,64-gapY,WHITE);
display.setCursor(100,0);
display.print(flappyScore);
display.display();
if(pressed(BTN_BACK))
{
currentState = MENU;
}
}
//=========================================
void resetPong()
{
paddleY = 25;
ballX = 64;
ballY = 32;
ballVX = 2;
ballVY = 2;
pongScore = 0;
}
//=========================================
void runPong()
{
if(digitalRead(BTN_A)==LOW)
paddleY -= 3;
if(digitalRead(BTN_B)==LOW)
paddleY += 3;
if(paddleY<0) paddleY=0;
if(paddleY>44) paddleY=44;
ballX += ballVX;
ballY += ballVY;
if(ballY<=0 || ballY>=63)
{
ballVY = -ballVY;
beep();
}
if(ballX<=5)
{
if(ballY>=paddleY &&
ballY<=paddleY+20)
{
ballVX = -ballVX;
pongScore++;
beep();
}
else
{
resetPong();
}
}
if(ballX>=127)
{
ballVX = -ballVX;
}
display.clearDisplay();
display.fillRect(0,paddleY,3,20,WHITE);
display.fillCircle(ballX,ballY,2,WHITE);
display.setCursor(100,0);
display.print(pongScore);
display.display();
if(pressed(BTN_BACK))
{
currentState = MENU;
}
}
//=========================================
void setup()
{
pinMode(BTN_UP, INPUT_PULLUP);
pinMode(BTN_DOWN, INPUT_PULLUP);
pinMode(BTN_SELECT, INPUT_PULLUP);
pinMode(BTN_A, INPUT_PULLUP);
pinMode(BTN_B, INPUT_PULLUP);
pinMode(BTN_BACK, INPUT_PULLUP);
pinMode(BUZZER, OUTPUT);
Wire.begin();
display.begin(
SSD1306_SWITCHCAPVCC,
0x3C
);
randomSeed(millis());
drawMenu();
}
//=========================================
void loop()
{
switch(currentState)
{
case MENU:
if(pressed(BTN_UP))
{
menuIndex--;
if(menuIndex<0)
menuIndex=1;
beep();
}
if(pressed(BTN_DOWN))
{
menuIndex++;
if(menuIndex>1)
menuIndex=0;
beep();
}
if(pressed(BTN_SELECT))
{
beep();
if(menuIndex==0)
{
resetFlappy();
currentState = FLAPPY;
}
else
{
resetPong();
currentState = PINGPONG;
}
}
drawMenu();
break;
case FLAPPY:
runFlappy();
delay(40);
break;
case PINGPONG:
runPong();
delay(25);
break;
}
}