Motivation
I want to replicate the game Flappy Bird but with some modifications in choosing the image and adding some sounds to it such as the background music and the cat’s sound when it is alive/dead.
Process
The game requires player to click mouse to move the cat upwards. If the mouse is not pressed, the cat will be falling down. By controlling the direction and the velocity of the cat, player needs to avoid hitting the palm trees which approach the cat from the right hand side. The final score is the number of times the cat flies through 2 palm tress.
I encountered first problems when trying to upload the sound file to Processing library. It seems Processing on my laptop cannot read the tail .mp3 so I had to have all the mp3 files converted to wav files. The example from processing.org uses mp3 and it works but not for my laptop. I think it can be related to the version of the software. Regarding the class Palm Tree, I used a not so technical method to draw the foliage. I drew a lot of triangles and put one on top of the other to (hopefully) give it a look like the palm tree. Firstly, I drew a palm tree using only triangles on a coordinate plane to check the coordinates of all the points I needed. Then I used Excel to organize all the numbers a bit and gradually form triangles by grouping 3 points together.
Code
Palm tree class
// Draw the palm tree public class palmTree { void draw(float x, float y, boolean flip){ smooth(); noStroke(); // Turn the palm trees upside down to create 2 lines of obstacles on both sides int flipper = 1; if (flip) flipper = -1; //Draw the tree trunk fill(94,62,28); //rect (0 + x,0 + y,50 + x,-200+y); rect(x, y, 50, -1000*flipper); //Draw the foliage by putting a lot of triangles on top of each other. //The numbers were collected from a mobile app allowing users to know the coordinates of each point when a random shape is drawn fill(62, 145, 32); triangle(50 + x, y, 0 + x, (57.5)*flipper + y, -39.25 + x, (19.25)*flipper + y); triangle(50 + x, y,-39.25 + x, (88.75)*flipper + y, 49.5 + x, (62.5)*flipper + y); triangle(50 + x, y, 49.5 + x, (62.5)*flipper + y, 86.25 + x, (11.75)*flipper + y); triangle(0 + x, y, 49.5 + x, (62.5)*flipper + y, 75 + x, (-40)*flipper + y); triangle(50 + x, y, 0 + x, (57.5)*flipper + y, 57.5 + x, (107.5)*flipper + y); triangle(0 + x, y, 0 + x, (57.5)*flipper + y, 90.75 + x, (76)*flipper + y); triangle(50 + x, y, 49.5 + x, (62.5)*flipper + y, -2 + x, (110)*flipper + y); triangle(50 + x, y, 0 + x, (57.5)*flipper + y, -30.5 + x, (-37.5)*flipper + y); fill(0); } }
Main class
import processing.sound.*; // Image files PImage background; PImage cat; // Sound files SoundFile backgroundMusic; SoundFile catAlive; SoundFile catDead; palmTree pt; PFont f; int interfaceState = 1; int point = 0; int max = 0; int x = -200, y; int catFallingSpeed = 0; int treeX[] = new int[2]; int treeY[] = new int[2]; void setup() { size(800,600); fill(0); textSize(40); background =loadImage("background.jpg"); cat =loadImage("cat.png"); cat.resize(0,70); backgroundMusic = new SoundFile(this,"jazz.wav"); backgroundMusic.play(); catAlive = new SoundFile(this, "catAlive.wav"); catDead = new SoundFile(this, "catDead.wav"); pt = new palmTree(); } boolean catDeadSoundPlayed = false; int closestPillar = 0; void draw() { if(interfaceState == 0) { imageMode(CORNER); image(background, x, 0); image(background, x+background.width, 0); //Make the background move to create the illusion that the cat is flying forwards x -= 5; catFallingSpeed += 1; y += catFallingSpeed; if(x <= -background.width) x = 0; for(int i = 0 ; i < 2; i++) { imageMode(CENTER); //Create the gap between two trees pt.draw(treeX[i], treeY[i] - 150, false); pt.draw(treeX[i], treeY[i] + 150, true); if(treeX[i] < 0) { treeY[i] = (int)random(200, height-200); treeX[i] = width; //point++; } if (treeX[i] < width/2 && i == closestPillar) { max = max(++point, max); closestPillar = 1 - closestPillar;} //Conditions when the game ends including reaching the boundaries or colliding with the palm tree blocks if (y > height || y < 0 || (abs(width/2-treeX[i])<25 && abs(y-treeY[i])>100)) interfaceState=1; treeX[i] -= 5; } image(cat, width/2, y); text(""+point, 20, 50); } else if (interfaceState==1) { if (!catDeadSoundPlayed){ catDead.play(); catDeadSoundPlayed = true; } imageMode(CENTER); // change to menu image image(background, width/2, height/2); text("High Score: "+max, 50, width/2); f = createFont("Courier New", 30); textFont(f); } } void mousePressed() { catAlive.play(); catFallingSpeed = -17; if(interfaceState==1) { treeX[0] = width; treeY[0] = y = height/2; treeX[1] = width*3/2; treeY[1] = 300; x = interfaceState = point = 0; catDeadSoundPlayed = false; } }
Final game (I cannot record the sound of it)
Rooms for improvement
In the game, as long as the cat does now hit the tree trunk which is in a rectangular shape, the cat is still alive and the player can keep playing. I do not know how to check if the cat hits the spiky shape of the foliage to end the game at that point so I use collision with the tree trunk only as a determiner if the game is still ok or should be ended.
Also, I did not loop the background music so if a player is playing so well and exceed the time duration of around 2 minutes (the length of the track), the background music disappears.
The file containing all related assets can be accessed here: flying_campus_cat
After making the game and listening to the cat sound several times when testing it, I walked out seeing a cat and it hit differently :<