I wanted to make a game so I did. My version of flappy bird is really similar to the original one and I am happy with the final version. It is very playable and fun. However, there are a few potential improvements I could have made but simply did not have time.
- I did not add a replay function to my game. Ideally, a button is clicked after each death and the player is able to restart the game.
- In my code, I should have made a Game class, where initializing and terminating the game takes place. This makes my main file a lot longer than it needs to be.
My full code/images/sounds can be found on
https://github.com/ross67/IntroToIm/tree/master/flappyBird
//main import processing.sound.*; 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); //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,225)); tubeListTop.add(new Tube(660+180*i,0,60,tubeLength, hSpeed)); } for (int i=0; i<4;i++){ tubeLength =int(random(120,225)); tubeListBot.add(new Tube(660+180*i,505-tubeLength,60,tubeLength,hSpeed)); } } void draw(){ if(!gameOver){ image(backgroundImg,0,0); bird = new Bird(x, y); textSize(20); fill(0, 102, 153); text("PRESS SPACEBAR TO FLY", 80,580); fill(255,0,0); text("Socre: " + 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{ 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; }
//classes class Bird{ float locx, locy; Bird(float x,float y){ locx = x; locy = y; } 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; } }