Created
October 15, 2015 13:05
-
-
Save yuraj11/99fa2c75dadf1e1bc517 to your computer and use it in GitHub Desktop.
Arduino flappy bird (Nokia 5110 LCD)
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
//Nokia 5110 LCD | |
//Preview https://www.youtube.com/watch?v=hSa_eCfRABM | |
//Uses U8glib https://github.com/olikraus/u8glib | |
//Written by Yuraj | |
#include <U8glib.h> | |
#include <EEPROM.h> | |
#define PIN_BL 3 //potentiometer for backlight | |
#define PIN_BL_POT A0 //backlight | |
#define PIN_BTN_L 4 //button | |
#define PIN_BTN_R 5 //button-reset | |
#define PIN_BUZZER 2 //buzzer | |
#define bird_width 5 | |
#define bird_height 5 | |
#define bird_start_y 20 | |
#define inloop_logo_width 84 | |
#define inloop_logo_height 30 | |
U8GLIB_PCD8544 u8g(13, 11, 10, 9, 8); | |
static uint8_t inloop_logo[] U8G_PROGMEM = { | |
0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, | |
0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x01, | |
0x00, 0x80, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, | |
0x80, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x80, | |
0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x0f, | |
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x0f, 0x00, | |
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0xc0, 0x07, 0x28, 0x00, | |
0x14, 0x00, 0x40, 0x01, 0x7c, 0xf0, 0xfc, 0xc1, 0x07, 0xfe, 0x81, 0x7f, | |
0xc0, 0xf7, 0x07, 0x7c, 0xf8, 0xff, 0xc1, 0x07, 0xff, 0xc3, 0xff, 0xfb, | |
0xff, 0x07, 0x7c, 0xf8, 0xff, 0xc1, 0x87, 0xff, 0xe3, 0xff, 0xff, 0xff, | |
0x0f, 0x3c, 0xf8, 0xff, 0xc1, 0xc7, 0xff, 0xf7, 0xff, 0xe7, 0xc7, 0x0f, | |
0x3e, 0xf8, 0xf0, 0xe1, 0xe3, 0xc7, 0xff, 0xf1, 0xe3, 0x87, 0x0f, 0x3e, | |
0xfc, 0xf0, 0xe1, 0xe3, 0x83, 0x7f, 0xe0, 0xe3, 0x83, 0x0f, 0x3e, 0x7c, | |
0xf0, 0xe1, 0xe3, 0x03, 0x7f, 0xe0, 0xe3, 0x83, 0x0f, 0x3e, 0x7c, 0xf0, | |
0xe1, 0xe3, 0x01, 0x3f, 0xe0, 0xe3, 0x83, 0x0f, 0x3e, 0x7c, 0xf8, 0xe0, | |
0xf3, 0x03, 0x3f, 0xe0, 0xf1, 0xc1, 0x07, 0x1f, 0x7c, 0xf8, 0xf0, 0xe3, | |
0x01, 0x3f, 0xe0, 0xf1, 0xc1, 0x07, 0x1f, 0x3e, 0xf8, 0xf0, 0xe1, 0xc3, | |
0x7f, 0xf0, 0xf1, 0xc1, 0x07, 0x1f, 0x3e, 0xf8, 0xf0, 0xe1, 0xe3, 0xff, | |
0xf8, 0xf1, 0xe1, 0x03, 0x1f, 0x3e, 0xf8, 0xf8, 0xe1, 0xff, 0xfb, 0xff, | |
0xf0, 0xfb, 0x03, 0x9f, 0x3f, 0xf8, 0xf8, 0xf1, 0xff, 0xf1, 0x7f, 0xf8, | |
0xff, 0x01, 0xff, 0x3f, 0xf8, 0xff, 0xdf, 0xff, 0xf0, 0x3f, 0xf8, 0xff, | |
0x00, 0x3e, 0x3e, 0xf0, 0xe3, 0x07, 0x3f, 0xc0, 0x1f, 0xf8, 0x3e, 0x00, | |
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x00, 0x00, | |
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x00, | |
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, | |
0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
0x00, 0x00, 0x00, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
0x00, 0x00, 0x00, 0x7c, 0x00, 0x00 }; | |
boolean isSplashScreen = true, gameOver, prevTap = false; | |
//Bird | |
int yPos, xPos; | |
int yVelocity; | |
int score, highScore; | |
const int yAccel = 1; | |
const int maxYVelocity = 6; | |
//Obstacles | |
typedef struct { int x; int gapStart; int gapEnd; } Obstacle; | |
#define MAX_OBSTACLES 5 | |
#define obstacle_width 6 | |
#define gap_size 20 | |
Obstacle obstacles[MAX_OBSTACLES]; | |
int curObstacle = 0; | |
int lastScoreObstacle; | |
char scoreBuf[4], highestScoreBuf[4]; | |
long tick = 0, tickObstacle = 0, tickObstacleUpdate = 0; | |
void generateObstalce() { | |
if (millis() - tickObstacle > 3000) { | |
int pad = 5, startPos = random(pad,u8g.getHeight() - gap_size - pad); | |
obstacles[curObstacle].x = u8g.getWidth(); | |
obstacles[curObstacle].gapStart = startPos; | |
obstacles[curObstacle].gapEnd = startPos + gap_size; | |
if ((curObstacle + 1) < MAX_OBSTACLES) { | |
curObstacle++; | |
} else { | |
curObstacle = 0; | |
} | |
tickObstacle = millis(); | |
} | |
} | |
void setGameOver() { | |
gameOver = true; | |
if (score > highScore) { | |
EEPROMWriteInt(0, score); | |
highScore = score; | |
} | |
tone(PIN_BUZZER, 225, 50); | |
} | |
void updateObstalces() { | |
// update pos | |
if (millis() - tickObstacleUpdate > 50) { | |
for (int i = 0; i < MAX_OBSTACLES; i++) { | |
obstacles[i].x -= 1; | |
//Check If bird overlaps obstacle | |
boolean betweenObstacle = xPos < (obstacles[i].x + bird_width) && xPos > (obstacles[i].x); | |
if (betweenObstacle && (yPos < obstacles[i].gapStart || (yPos + bird_height) > obstacles[i].gapEnd)) { | |
setGameOver(); | |
} else { | |
if (betweenObstacle && i != lastScoreObstacle) { | |
score++; | |
lastScoreObstacle = i; | |
} | |
} | |
} | |
tickObstacleUpdate = millis(); | |
} | |
} | |
void updateBird(boolean tap) { | |
if (tap) { | |
yVelocity = -4; | |
} | |
if (millis() - tick > 50) { | |
yVelocity += yAccel; | |
if (yVelocity > maxYVelocity) { | |
yVelocity = maxYVelocity; | |
} | |
if (yPos + bird_height >= u8g.getHeight() || yPos <= 0) { | |
setGameOver(); | |
} | |
yPos += yVelocity; | |
tick = millis(); | |
} | |
} | |
void resetGame() { | |
for (int i = 0; i < MAX_OBSTACLES; i++) { | |
obstacles[i].x = -5; | |
obstacles[i].gapStart = 0; | |
obstacles[i].gapEnd = 0; | |
} | |
gameOver = false; | |
yPos = bird_start_y; | |
yVelocity = -4; | |
score = 0; | |
lastScoreObstacle = -1; | |
} | |
void draw(boolean tap) { | |
u8g.setFont(u8g_font_5x8r); | |
if (isSplashScreen) { | |
u8g.drawXBMP(0, 0, inloop_logo_width, inloop_logo_height, inloop_logo); | |
u8g.drawStr(0, 42, "EVERYTHING MOBILE"); | |
if (tap) { | |
isSplashScreen = false; | |
} | |
} else { | |
if (gameOver) { | |
if (tap) { | |
resetGame(); | |
} | |
u8g.drawStr(0, 22, "> TAP to play <"); | |
u8g.drawStr(10, 35, "Best score: "); | |
u8g.drawStr(65, 35, highestScoreBuf); | |
} else { | |
//Draw obstacles | |
for (int i = 0; i < MAX_OBSTACLES; i++) { | |
if ((obstacles[i].x + 5) > 0) { | |
u8g.drawBox(obstacles[i].x, 0, obstacle_width, obstacles[i].gapStart); | |
u8g.drawBox(obstacles[i].x, obstacles[i].gapEnd, obstacle_width, u8g.getHeight()); | |
} | |
} | |
//Draw ground | |
u8g.drawBox(0, u8g.getHeight() - 1, u8g.getWidth(), 1); | |
//Draw bird | |
u8g.drawBox(xPos, yPos, bird_width, bird_height); | |
} | |
//Draw score | |
u8g.drawStr(0, 8, scoreBuf); | |
} | |
} | |
void setup() | |
{ | |
pinMode(PIN_BL, OUTPUT); | |
pinMode(PIN_BL_POT, INPUT); | |
pinMode(PIN_BTN_L, INPUT); | |
pinMode(PIN_BUZZER, OUTPUT); | |
u8g.setRot180(); | |
u8g.setColorIndex(1); | |
highScore = EEPROMReadInt(0); | |
xPos = (u8g.getWidth() / 2) - (bird_width / 2); | |
resetGame(); | |
gameOver = true; | |
} | |
boolean wasReseted = false; | |
void loop() | |
{ | |
boolean tap = digitalRead(PIN_BTN_L); | |
boolean tappedOnly = tap && !prevTap; | |
if (digitalRead(PIN_BTN_R)) { | |
EEPROMWriteInt(0, 0); | |
highScore = 0; | |
delay(1000); | |
} | |
u8g.firstPage(); | |
do { | |
draw(tappedOnly); | |
} while (u8g.nextPage()); | |
if (!gameOver) { | |
updateBird(tappedOnly); | |
generateObstalce(); | |
updateObstalces(); | |
} | |
itoa(score, scoreBuf, 10); | |
itoa(highScore, highestScoreBuf, 10); | |
analogWrite(PIN_BL, map(analogRead(PIN_BL_POT), 0, 1023, 0, 255)); | |
prevTap = tap; | |
} | |
//http://forum.arduino.cc/index.php/topic,37470.0.html | |
//This function will write a 2 byte integer to the eeprom at the specified address and address + 1 | |
void EEPROMWriteInt(int p_address, int p_value) | |
{ | |
byte lowByte = ((p_value >> 0) & 0xFF); | |
byte highByte = ((p_value >> 8) & 0xFF); | |
EEPROM.write(p_address, lowByte); | |
EEPROM.write(p_address + 1, highByte); | |
} | |
//This function will read a 2 byte integer from the eeprom at the specified address and address + 1 | |
unsigned int EEPROMReadInt(int p_address) | |
{ | |
byte lowByte = EEPROM.read(p_address); | |
byte highByte = EEPROM.read(p_address + 1); | |
return ((lowByte << 0) & 0xFF) + ((highByte << 8) & 0xFF00); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment