Have you ever wondered how the bird feels when it tirelessly flaps its wings through the never-ending tube maze? Look no further than this revolutionary interactive new flappy bird playing experience!
Step 1: Strap the Flappy-Bird Controller® tightly onto your hand like this:

Step 2: Flap away! Now you can get addicted to this stupid game all over again!
I made the Flappy-Bird Controller® with a tilt sensor wired in a serial circuit. The tilt censor only returns a 1 or a 0 and arduino sends that number to processing. Processing tracks the previous input and the bird only flaps when the previous number is 0 and the current input is 1. Below are my codes:
Arduino:
int inPin = 2; // the number of the input pin
int reading; // the current reading from the input pin
int previous = LOW; // the previous reading from the input pin
// the following variables are long because the time, measured in miliseconds,
// will quickly become a bigger number than can be stored in an int.
long time = 0; // the last time the output pin was toggled
long debounce = 50; // the debounce time, increase if the output flickers
void setup()
{
Serial.begin(9600);
pinMode(inPin, INPUT);
}
void loop()
{
int switchstate;
reading = digitalRead(inPin);
// If the switch changed, due to bounce or pressing...
if (reading != previous) {
// reset the debouncing timer
time = millis();
}
if ((millis() - time) > debounce) {
// whatever the switch is at, its been there for a long time
// so lets settle on it!
switchstate = reading;
}
Serial.write(switchstate);
// Save the last reading so we keep a running tally
previous = reading;
}
Processing:
main:
import processing.sound.*;
import processing.serial.*;
Serial myPort;
int fly=0;
int previous = 0 ;
SoundFile hit;
SoundFile die;
SoundFile point;
SoundFile wing;
PImage backgroundImg;
PImage img1;
PImage img2;
PImage img3;
PImage img;
PImage tube1;
PImage tube2;
int background =0;
boolean state = false;
boolean gameOver = false;
float speed = 0;
float gravity = 0.1;
int score = 0;
int hSpeed = 2;
float x = 50;
float y = 200;
int tubeLength;
Bird bird;
Tube tube;
ArrayList<Tube> tubeListTop;
ArrayList<Tube> tubeListBot;
void setup(){
size(600,600);
printArray(Serial.list());
String portname=Serial.list()[9];
println(portname);
myPort = new Serial(this,portname,9600);
//size(1440,900);
backgroundImg = loadImage("bg.png");
img1 = loadImage("upflap.png");
img2 = loadImage("midflap.png");
img3 = loadImage("downflap.png");
tube1 = loadImage("tube1.png");
tube2 =loadImage("tube2.png");
tubeListTop = new ArrayList<Tube>();
tubeListBot = new ArrayList<Tube>();
img = img3;
hit = new SoundFile(this, "hit.wav");
die = new SoundFile(this, "die.wav");
point = new SoundFile(this,"point.wav");
wing = new SoundFile(this, "wing.wav");
for (int i=0; i<4;i++){
tubeLength =int(random(120,200));
tubeListTop.add(new Tube(660+180*i,0,60,tubeLength, hSpeed));
}
for (int i=0; i<4;i++){
tubeLength =int(random(120,200));
tubeListBot.add(new Tube(660+180*i,505-tubeLength,60,tubeLength,hSpeed));
}
}
void draw(){
if(!gameOver){
println(fly+","+previous);
img = img1;
if(fly==1 && previous ==0){
img = img3;
wing.play();
y = y-30;
speed = speed *0.02;
}
previous = fly;
image(backgroundImg,0,0);
bird = new Bird(x, y);
textSize(20);
fill(0, 102, 153);
text("FLIP YOUR WING TO FLY", 80,580);
fill(255,0,0);
text("Score: " + score, 450, 580);
//if(keyPressed==true){ // use keyboard to move bird
// if(key == 'w'){
// y--;
// }else if(key== 'a'){
// x--;
// }else if(key=='d'){
// x++;
// }else if(key=='s'){
// y++;
// }
//}
for(Tube tube:tubeListTop){
if(tube.locx<-60){
tube.setX(680);
}
tube.draw();
}
for(Tube tube:tubeListBot){
if(tube.locx<-60){
tube.setX(680);
}
if (bird.locx == tube.locx){
score++;
point.play();
}
tube.drawInverse();
}
}else{
// image(backgroundImg,0,0);
//bird = new Bird(x, y);
textSize(38);
text("GAME OVER",180,270);
textSize(16);
text("restart the program to try again",170,290);
}
// Add speed to location.
y = y + speed;
// Add gravity to speed.
speed = speed + gravity;
if (y > height-123) {
// Multiplying by -0.40 instead of -1 slows the object
// down each time it bounces (by decreasing speed).
// This is known as a "dampening" effect and is a more
// realistic simulation of the real world (without it,
// a ball would bounce forever).
speed = speed * -0.40;
y = height-123;
}
bird.draw(img);
for(Tube tube:tubeListTop){
if(bird.onCollision(tube)&&!gameOver){
gameOver = true;
hit.play();
delay(100);
die.play();
}
}
for(Tube tube:tubeListBot){
if(bird.onCollision(tube)&&!gameOver){
gameOver = true;
hit.play();
delay(100);
die.play();
}
}
}
//void keyPressed(){
//img = img1;
//wing.play();
//}
//void keyReleased(){
// y = y-30;
// speed = speed *0.05;
// img = img3;
// }
void serialEvent(Serial myPort){
fly=myPort.read();
}
Bird class:
class Bird{
float locx, locy;
Bird(float x,float y){
locx = x;
locy = y;
}
//void gravity(){
// // Add speed to location.
// locy = locy + speed;
//// Add gravity to speed.
// speed = speed + gravity;
//}
void draw(PImage img ){
image(img,locx,locy);
}
boolean onCollision(Tube a) {
// are the sides of one rectangle touching the other?
if (locx + 36 >= a.locx && // r1 right edge past r2 left
locx <= a.locx + a.xlen && // r1 left edge past r2 right
locy + 26 >= a.locy && // r1 top edge past r2 bottom
locy <= a.locy + a.ylen) { // r1 bottom edge past r2 top
return true;
}
return false;
}
//http://www.jeffreythompson.org/collision-detection/rect-rect.php
}
class Tube{
int locx, locy, xlen, ylen, hSpeed;
Tube(int x,int y, int xl, int yl, int hs){
locx = x;
locy = y;
xlen = xl;
ylen = yl;
hSpeed = hs;
}
void draw(){
image(tube1,locx,locy,xlen,ylen);
locx -= hSpeed;
}
void drawInverse(){
image(tube2,locx,locy,xlen, ylen);
locx -= hSpeed;
}
void setX(int x){
locx =x;
}
}