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;
}
}