#include <TinyWireM.h>
#include <Tiny4kOLED.h>
// UP button
int btn1 = PB3;
// Down button
int btn2 = PB4;
// Button Debounce delay
int debounceDelay = 200;
// Animation Speed
int speed = 300;
// variables
int mode = 0;
int pos = 5;
int k = 4;
int x = 0;
bool win;
int score = 0;
unsigned long lastMillis;
void setup() {
oled.begin();
pinMode(btn1, INPUT_PULLUP);
pinMode(btn2, INPUT_PULLUP);
// random seed for generating random numbers
randomSeed(analogRead(1));
// Two rotations are supported,
// The begin() method sets the rotation to 1.
//oled.setRotation(0);
oled.setFont(FONT6X8);
oled.on();
// To clear all the memory, clear both rendering frames:
oled.clear();
oled.switchRenderFrame();
oled.clear();
oled.switchRenderFrame();
}
void loop() {
// manu mode
if (mode == 0) {
oled.setCursor(30, 0);
oled.print(F("Floppy Bird"));
oled.setCursor(0, 1);
oled.fillToEOL(0x10);
oled.setCursor(20, 3);
oled.print(F("start the game"));
oled.setCursor(0, 5);
oled.print(F("switch off the screen"));
// Press up button to enter the game
if (digitalRead(btn1) == LOW) {
oled.setCursor(0, 4);
oled.fillToEOL(0x0C);
mode = 1;
delay(300);
// clear the screen
oled.clear();
oled.switchRenderFrame();
oled.clear();
oled.switchRenderFrame();
}
// Press the down button to turn off the screen
if (digitalRead(btn2) == LOW) {
oled.setCursor(0, 6);
oled.fillToEOL(0x0C);
mode = 2;
delay(300);
}
}
// Off screen mode
if (mode == 2) {
oled.clear();
oled.switchRenderFrame();
oled.clear();
oled.switchRenderFrame();
// when the screen is turned off,
// press down button to turn it on again
if (digitalRead(btn2) == LOW) {
mode = 0;
delay(debounceDelay);
}
}
// Game mode
if (mode == 1) {
// move the bird Down by pressing down button
if (digitalRead(btn2) == LOW) {
oled.setCursor(10, pos);
oled.print(F(" "));
pos++;
// limit the downward movement
if (pos > 7) {
pos = 7;
}
delay(debounceDelay);
}
// move the bird Up by pressing up button
if (digitalRead(btn1) == LOW) {
oled.setCursor(10, pos);
oled.print(F(" "));
pos--;
// limit the upward movement
if (pos < 0) {
pos = 0;
}
delay(debounceDelay);
}
// display the bird
oled.setCursor(10, pos);
oled.print(F("e"));
// generate the open space
openWall(120 - (x * 10), k);
openWall(120 - (x * 10), k + 1);
// generate the walls
for (int i = 0; i < k; i++) {
solidWall(120 - (x * 10), i);
}
for (int i = k + 2; i < 8; i++) {
solidWall(120 - (x * 10), i);
}
// move the walls forward in every render time
if (millis() - lastMillis > speed) {
lastMillis = millis();
// clear the previous wall
clearWall();
x++;
// reset the x coordinate when it hits max distance
if (x > 12) {
x = 0;
// generate random number for the next open space
k = random(1, 7);
}
// increase the score when the bird successfully
// enters through the open space
if (win) {
score += 1;
win = false;
}
}
// check if the bird enters through the open space
// or crashes into the wall
if (x == 11) {
// entered through the open space
if (pos == k || pos == k + 1) {
oled.setCursor(10, pos);
oled.print(F("e"));
win = true;
}
// collides with the wall
else {
// change the mode to menu mode
mode = 0;
oled.setCursor(10, pos);
oled.print(F(" "));
oled.setCursor(30, 2);
oled.print(F("Game Over!"));
// display score
oled.setCursor(30, 4);
oled.print(F("Score : "));
oled.print(score);
delay(3000);
// clear the screen and exit the game mode
oled.clear();
oled.switchRenderFrame();
oled.clear();
oled.switchRenderFrame();
}
}
}
}
// generates solid walls
void solidWall(int px, int py) {
oled.setCursor(px, py);
oled.startData();
for (int i = 0; i < 7; i++) {
oled.sendData(255);
}
oled.endData();
}
// generates open space in the wall
void openWall(int px, int py) {
oled.setCursor(px, py);
oled.startData();
for (int i = 0; i < 7; i++) {
oled.sendData(0);
}
oled.endData();
}
// remove the wall
void clearWall() {
for (int i = 0; i < 9; i++) {
oled.setCursor(120 - (x * 10), i);
oled.startData();
for (int i = 0; i < 7; i++) {
oled.sendData(0);
}
oled.endData();
}
}