Flappy Bird: Make A Classic Game using Javascript & P5.js Framework | Saran Siri | Skillshare

Playback Speed


  • 0.5x
  • 1x (Normal)
  • 1.25x
  • 1.5x
  • 2x

Flappy Bird: Make A Classic Game using Javascript & P5.js Framework

teacher avatar Saran Siri, Instructor

Watch this class and thousands more

Get unlimited access to every class
Taught by industry leaders & working professionals
Topics include illustration, design, photography, and more

Watch this class and thousands more

Get unlimited access to every class
Taught by industry leaders & working professionals
Topics include illustration, design, photography, and more

Lessons in This Class

12 Lessons (39m)
    • 1. Promo

      0:52
    • 2. Basics

      7:02
    • 3. Bird

      2:52
    • 4. Drop

      3:39
    • 5. Flap

      3:07
    • 6. Death

      4:14
    • 7. Pipe

      3:35
    • 8. Illusion

      4:00
    • 9. Collision

      3:09
    • 10. Score

      3:01
    • 11. Final Touch

      2:24
    • 12. Share

      0:43
  • --
  • Beginner level
  • Intermediate level
  • Advanced level
  • All levels

Community Generated

The level is determined by a majority opinion of students who have reviewed this class. The teacher's recommendation is shown until at least 5 student responses are collected.

59

Students

1

Project

About This Class

This is my game tutorial series where I teach javascript and P5.js framework using classic games.

Check out other games

In this class, we will make a classic Flappy Bird game using free online P5.js editor

P5* editor => https://editor.p5js.org

Meet Your Teacher

Teacher Profile Image

Saran Siri

Instructor

Teacher

Will you please follow me because you will love watching my new classes I publish?

Learning code from fun exercises is the best way to start with. I've spent all my free-time making courses like these. If you like highly edited videos, feel free to follow me for more to come.

Do you have Skillshare Premium?

Skillshare Premium is required to watch most of my courses because it gives me the chance to earn money based on every minute you spend watching. I have a Skillshare Premium subscription that gives me unlimited access to all Skillshare courses free for the first month and then $96 a year after that which is just $8 per month! This is how I prefer to take online courses because I complete payment once and then I am able to lear... See full profile

Class Ratings

Expectations Met?
    Exceeded!
  • 0%
  • Yes
  • 0%
  • Somewhat
  • 0%
  • Not really
  • 0%
Reviews Archive

In October 2018, we updated our review system to improve the way we collect feedback. Below are the reviews written before that update.

Why Join Skillshare?

Take award-winning Skillshare Original Classes

Each class has short lessons, hands-on projects

Your membership supports Skillshare teachers

Learn From Anywhere

Take classes on the go with the Skillshare app. Stream or download to watch on the plane, the subway, or wherever you learn best.

Transcripts

1. Promo: Hi, my name is Saran. In this course, I will show you how to make a simple, easy-to-follow, classic Flappy Bird game, using JavaScript and P5 framework. We will be using a free online editor that runs on any web browser. I will show you how to draw the basic shapes, and make an object move. Then I will draw a bird, make it drop to the ground by simulating the gravity. Make the bird jump, and make it stop jumping when it's dead. Then I would create the moving pipes, and add the collision detection to the pipes. Finally, I will add the score system and make it harder. You can follow me for more game tutorials. Now let's open the next lesson, and get started! 2. Basics: In this first video, we will talk about the basics of P5.js framework. Open a browser, and go to editor.p5js.org. On this screen, we have the coding panel on the left, and a preview on the right. Click the run button, to execute the code. The result will be shown on the right. I recommend creating an account right away, because you can save the projects and avoid, accidentally, refreshing the site, which clears the progress you have made. Once you do that, rename the title to "Flappy Bird", and save it. You can browse your saved projects in the Open menu. To make it easier to see, we will be using the dark theme from now on. In here, we have two basics functions -- the setup function, and the draw function. The setup function contains code for assigning the initial values. Code inside the curly brackets will be run only once at the beginning. In it, there's one function inside -- createCanvas, which sets the display screen to 400 pixels width, and 400 pixels height. We can change the width to 600. Then click run, to see the change. Let's change it back to 400. In the draw function, we have called a background function which paints the entire screen with 220. 220 is a light grey colour on the greyscale. Change it to 0 for the darkest colour, or 255, for the brightest colour. For other colours, we can google "RGB color picker", and pick the colour that we want. In this case, we want a colour of a blue sky. Then, copy these RGB numbers, and put them inside the background parentheses. When we hit run, the code in the setup function is called. Then the draw function is called repeatedly, which means whatever inside the draw function is being called 60 times per second, or 60 FPS by default. For example, if we call a function print, parentheses, frameCount, and hit run. We will see that it prints the frameCount to the console window below, at the rate of 60 lines per second. We can slow it down by setting the frameRate to 1 frame per second. Now in the console, it draws the blue sky, and prints the frame count every second. 60 is the default rate. So let's remove that. Let's talk about the coordinate system. In most 2D game engines, the origin starts at the top left corner, where the x position is 0 and y position is 0. Moving to the right increases the x-value. Moving downwards increases to y value. This is the opposite of what a normal coordinate system uses. So please keep that in mind. Next, let's draw the basic shapes that we will use in our game. The first one is a rectangle. I will make a comment here. You don't need to write down. We would call a rect function which needs 4 input parameters. x position, y position, its width, and its height. To draw a 60 x 30 rectangle at the top left corner, we call rect x 0, y 0, width 60, and height 30. The x and y in a rectangle define where the top-left position should be. So we can say that the pivot is at the top-left corner. To move the rectangle to the centre. We will change x position to width/2, and y to height/2. Width and height highlighted in pink are the constant variables from the canvas -- from here. The next shape is an ellipse. To draw an ellipse, we need to specify 4 parameters. x, y, horizontal diameter, and vertical diameter. If the horizontal and the vertical diameter are the same, it is a circle. Let's draw a circle on top of the rectangle. ellipse, parentheses, half of the width, half up to height. Horizontal diameter is 50, and vertical diameter is also 50. Run it. Unlike a rectangle where the pivot is at the top-left corner, an ellipse pivot is at the centre. Next, let's talk about changing colours. To change the colour of this rectangle, we call a fill function before drawing the rectangle, The few function uses the same parameter types as the background function. It could be 1 greyscale number, or 3 RGB numbers. If I want to fill the rectangle with a green colour, it would be, fill, red 0, green 255, and blue 0. Then after drawing the rectangle, I could switch the fill colour to red. So fill, red 255, green 0, and blue 0. To remove the outlines, use noStroke in the setup function. Finally, let's talk about the animation. Even though on the previous screen, it looks like a still image, the draw function is running 60 times per second. Let's change the x position to frameCount. Because the frameCount goes up by 1 in every frame. When the draw function is called, the rectangle is now moving to the right, starting at 1. And it eventually travels out of the screen. Now that we've covered the basics, in the next video, we will create a Flappy Bird. Thank you. 3. Bird: In this video, we will use class in JavaScript. To learn more about it, I recommend a quick read from W3Schools website. In order to make our code easy to organize, we will create a bird class in a new file. Click on the arrow icon to show the sketch folder. Then click on Create File, name a file "bird.js". Go to the index.html file, and add bird.js, as part of the scripts. This open bird.js, we will create a bird class, class, Bird, and a pair of brackets. We need a constructor to create a bird object. constructor, parentheses, and brackets. In here, we will initialize the bird's X and Y position. this, dot, which refers to the variables within the class. Then x equals 1/3 of the screen width, this.y equals half of the screen height. We also need to define the bird's size. Let's make it 5% of the screen width, also, the bird class should handle its own drawing. So we will create a draw function, which will be called later in the sketch file. And let's draw a circle using the local variable x and y, ellipse, this x, this y, its size for the width, and its size for the height. Then go to the sketch file, On the very top, create a global variable named bird. In the setup, initialize the bird by making it equal to new Bird, parentheses. Then in the draw function, draw the bird, bird, dot draw. Run it. Now we shows the bird. Let's finish this by changing its colour. I'm going to use the colour picker again, and pick a yellow colour. Copy its RGB numbers. Then add a fill function, paste the number in, and that's it. In the next video, we will add physics to the game. Thank you. 4. Drop: Let's talk a bit about the acceleration of the moving objects. To make an object move, we have to constantly change its position. For example, I have the velocity set to 1, and we will add the velocity to the position x. The new x, equals, the old x, plus, velocity. So we could say that this block is moving at the constant speed of 1 pixel per frame. Now, if we want to move it faster and faster, when the time goes on, we could increase the velocity in every frame, by adding another variable to it, which we can call it acceleration. If the acceleration equals 1, it means that the velocity would start from 1, then 2, then 3, and so on. We could simulate a falling object using this concept. Back to the Bird class, we are going to simulate the gravity by first create a velocity on the y direction. this.vy equals 1. Then before drawing the bird, add the velocity to the y position. The new y equals the old y, plus velocity y. Now it moves downwards at the constant speed. We will introduce the acceleration. Set vy to 0. Then add ay equals 0.15. Before updating the y position, we will increase the velocity. The new vy is the old vy, plus ay. Even though ay, is just 0.15, the velocity adds up, and the bird is flying out of the screen. We need a floor at the bottom. So when the bird hits the floor, the game ends, and it should stop moving. Go to the sketch file, create a global variable, floorY. Let's set the floor to be at 90% of the screen height -- 0.9 * height. Then draw the floor behind the bird. We use rect, x is 0, y is floorY, width is the screen width, and height is the screen height, minus floorY. Make it brown by adding a fill function above it. Pick a brown colour, and call fill, then the colour numbers. Finally, we could stop the bird form going through the floor. Back to the Bird class, in the draw function, ask if, the position of y is greater than floorY from the sketch. If it is true, the code inside brackets will be called, and we want it to stop moving. So both velocity and acceleration should be 0. Finally, if it goes below the floor, the bird should land at the surface of the floor. The position of y should be equal to the floorY. And that's how to drop the bird to the floor. In the next video, we will be working on flapping its wings. Thank you. 5. Flap: The bird should jump when it receives an input from a user. It could be from a mouse click or pressing a spacebar on the keyboard. I will show you both ways. First, below the draw function, add our own function, call it -- doAction. This function will handle the jumping part, then add a system function called mousePressed. This function will be called every time a user presses a mouse button. When the user clicks inside the screen, it should call doAction. Below that, add another system function called keyPressed. This function will be called every time a user presses any key on the keyboard. To check if the space key is pressed. Ask if key, ==, two single quotes, and put a space inside. If is true, then we call doAction. Now doAction should make the bird jump. Let's implement the jumping part in the Bird class. Create a new function called jump. This part is not realistic, but when the bird jumps, we will force its velocity to be 0. vy equals 0. And then, make it accelerate upwards against the gravity. ay equals -1.7. Let's go back to the sketch file, and implement the jump function. Inside the doAction, put bird, dot jump. Now it goes out of the screen because it's moving faster in the opposite direction. The acceleration should, however, gradually, switch back to its original 0.15. To do that, we will make another constant variable -- aMax, set it to 0.15, set ay to aMax. Then above the if statement, we will ask if the current ay is less than aMax. This is true whenever the bird jumps, because now it's on the negative side, we have to increase it. So the new ay, equals old ay, plus an increasing rate, which for now let's make it 0.4. It would keep adding up until the if statement is false. When it is false, we want to limit it to the max value. So else, set the ay, to the aMax. The bird can now flap its wings. In the next video, we will implement the death screen. Thank you. 6. Death: The bird, on the floor, should not be able to jump. We will create a new variable called health. Set it to 1. When the bird hits the floor, we will not only stop the movement, but also kill the bird, by setting its health to 0. With this variable, we can then ask in the sketch, that only if the bird is alive, it can jump. bird dot health, ==, 1. Now after it hits the floor, it cannot jump anymore. Another place to kill the bird is when it goes above the screen. We will ask, if the position of y is less than 0, then y should be at 0. Reset the velocity back to 0. And it could start accelerating at the maximum speed -- aMax. And finally, kill it, health equals 0. Now when it hits the screen, it cannot jump anymore. Next, let's show the text on the screen when the bird is dead. Go to the sketch file, in the draw function, we can ask if the bird is dead. If health is 0, then call the text function. The text function has 3 parameters -- the texts as in string, x position and y position. We want to show "GAME OVER" at the centre of the screen. Let's change the text colour to black. Above the if statement, call the fill function, set it to 0. The default pivot of the text is at the bottom-left corner, which is hard to make it centred. However, there's a function called textAlign, which can move the pivot to all 9 positions. We we use CENTER, CENTER. On top of the text. textAlign, CENTER, CENTER. Finally, call the textSize, and set the size to 30. Now when the bird is dead, clicking on the screen or pressing a space key again, should revive the bird and restart the game. In the bird class, we will create another function to reset all the variables. Let's call it reset. This will reset everything back to the original values from the constructor. Only the constant values like size and aMax that don't change. Anything else, should go to the reset function. Cut them, and put them in the reset function. Then call reset at the end of the line. Finally, go to the sketch file. And when the bird is dead, the doAction should reset the bird's values. When if statement is false, it goes to else. Inside it, add bird, dot reset. And that's it. The game resets itself after the bird is dead. In the next video, we will create a pipe. Thank you. 7. Pipe: There's a lot of variables in the pipe. First, it needs to have an x position to keep track where it is horizontally. It doesn't need y position because it's always at the top. The pipe has a middle gap where the bird can pass through. We need to know where the gap starts, let's call it topGap. And the height of the gap itself, let's call it gapHeight. Finally, the width of the gap. Let's call that gapWidth. Create a new file, call it "pipe.js", add it to the index file. Inside it, create a Pipe class. The pipe has the constructor that receives the starting position of x. Create a local variable x, and assign it to the given x, add the gapWidth, and set it to 15% of the screen width, a gapHeight, set it to 30% of the screen height. The last one is topGap. So we are going to use a map and a random function. The map function has 5 parameters -- the number, the lowest point of that number, the highest point of that number, the new low, and the new high. And the random function has 2 parameters -- the lowest number it could be, and the highest number it could be. First, we call random to get a random number between 0 and 1. Then use this as the first parameter of the map function. Tell the map that the first parameter has the lowest point at 0, to the highest point at 1. Then we want the topGap to be from 10% of the height, to less than 60% of the height. Let's create a draw function. Let's pick a green colour to fuel the pipe, call the fill function, and put the colour into it. Draw the top part of the pipe using rect, x is x, y is 0, which is the gapWidth, height is the topGap. The bottom part starts with x. y is at a topGap, plus the gapHeight. Width is the same -- gapWidth. And height is the screen height, minus topGap, minus gapHeight. We would test this out using just one pipe for now. Go to the sketch file, create a global variable -- pipe. Assign it in the setup function. pipe equals new Pipe, and put 0 into the constructor. Draw it behind the floor, pipe dot draw. And that's it. In the next video, we will create multiple pipes. Thank you. 8. Illusion: Within this camera frame, it looks like there are infinite objects moving from right to left. Even though in reality, we just moved the same object to the right side when it's out of the screen. Since we can only see 3 pipes on the screen at a given time, we only need 3 pipes to create this effect. Change the name from pipe to pipes, and set it to an empty array. We will put 3 pipes into it. Create a for loop. var i, equals 0, i < 3, i++. Then for each pipe, pipes at i, equals a new pipe object. The first pipe will start at the screen width. The next pipe will start at the half of the screen width, times i. Copy this loop, and use it in the draw function. Inside the loop, we are going to draw each pipe, pipes at i, dot draw. We can also use pipes dot length, to get the number of pipes. We should see nothing here because the pipes haven't moved jet. Let's go to the pipe class. After drawing the pipe, move the pipe to the left, by typing the new x, equals the old x, minus 2. Then when the pipe goes beyond a certain range, loop it back to the far right. If x is less than negative half of the width, move the x back to the screen width, plus half of the gapWidth. After it is moved to the far right, we should also randomize the topGap, so it looks like a different pipe. Copy the top gap, and paste it inside the if statement. Now it looks like we have infinite pipes, with different topGaps coming through. Next, the pipes should stop moving as soon as the bird is dead. We can send the bird object to the pipes' draw function, which goes to the draw function, add bird to the parameter. Then ask if bird is still alive. Only when it's alive, the pipe can move. Finally, the pipe should have a function to reset itself when we restart the game, just like the bird. And a reset function, we need to store the original x position to another variable. So in the constructor, add x0, equals x, then move x, along with the topGap, to the reset function. When the pipe resets, x is set to x0, then call the reset in the constructor. Finally, when we reset the bird inside the doAction, we should reset all the pipes too. Copy the for loop from drawing pipes. Go through each pipe, and call the reset function. Now the gaps are randomized in every game. In the next video, we will make the bird hits the pipes. Thank you. 9. Collision: The bird dies when it collides with a pipe. We need to narrow it down where the bird should not go in x direction. So if its x, plus its radius, is greater than the x position of the pipe. If the left side of the equation goes beyond that, it enters the true zone, let's narrow it down further. Use and. If the bird's x, minus its radius, is less than pipe's x, plus the gapWidth. If both conditions are true, it might hit the pipe. Let's write this down first. Next, we have to check if the bird hits either the top or the bottom of the pipe. So if the bird's y, minus its radius, is less than topGap. With this condition, we have the top part. Then use or, the bird's y, plus its radius, is greater than topGap, plus its gapHeight. Now the true zone is in these two areas. Let's write that down. Inside the first if, add another if. If it is also true, then we kill the bird -- set its health to 0. Next, if the bird dies from hitting the side of the pipe, the bird should fall to the ground. But if it dies inside a gap, either from hitting the top gap, on the bottom gap, the bird should fall, and land on the bottom gap. First, go to the Bird class, and add the floor valuable. Set it to floorY. Change from dropping to floorY, to this dot floor. Also in here too. When the reset is called, the floor should set back to floorY. Then in the pipe class, when the bird dies, we have to check whether it dies within the gap. If the bird's x is greater than the pipe's x and, the bird's x is less than the pipe's x, plus the gapWidth. If it's true, the bird should land on the bottom gap. Let's write the code down. After we kill the bird, if it dies in here, set the bird's floor, to the topGap, plus gapHeight. Otherwise, it's going to fall down to the floorY. And that's it. In the next video, we will add the score system to the game. Thank you. 10. Score: The score should increase when the bird passes the end of the pipe, which is the pipe's x, plus its gapWidth. And the hiscore should show the best score you have done. We will add the score and the hiscore inside the Bird class. When the bird is reset, the score should be 0. The hiscore should be in the constructor as it won't get reset throughout the game. To increase the score, every pipe should hold a score of 1. Add it to the reset function. score equals 1. When the bird passes the pipe, the pipe hands over the score to the bird. Ask if the bird's x, is greater than the pipe's x, plus its gapWidth, which is the right edge of the pipe. and, if the pipe still holds the score of 1, which is greater than 0. Decrement the pipe's score, and increment the bird's score. When the pipe is out of the screen, restore the score back to 1. Let's test it out, by drawing the score in the sketch. In the draw function, add a text function -- show the text. text, score, colon, a space, plus bird dot score, show it at 10, 10. Above that, let's change the text alignment to LEFT, TOP. And change the textSize to 16. Run it. Now that it works, let's figure out the hiscore. In the bird class, we will compare the score to the hiscore. If the score is greater than the hiscore, then it is the new high score. Back to the sketch, show the hiscore, hiscore, colon, space, plus bird dot hiscore, show it at 10, 30. Run it. and that's it. In the next video, I will make the game harder. Thank you. 11. Final Touch: One of the things that we can do to make it harder is to make the pipes move faster when the score increases. First, create a global variable called pipeSpeed, and set it to 2. Now go to the Pipe class, and replace 2 with the pipeSpeed. Back in the sketch, we will slowly increase the pipeSpeed using the bird's score. PipeSpeed equals 2, plus bird's score, divided by 10. You could make it faster by lowering this number. Next, let's freeze the game when it first runs. Add a global variable, name it freeze. Assign it to true. Then every time the doAction is called, we unfreeze the game. freeze equals false. Then in the bird class, we should not update the position when the game is freezing. So wrap them within the if statement, and ask if it is not freezing. Another place to add, is in the pipe class, we need to check if the game freezes before we update the x position. So add freeze equals false to the if statement, along with an and operator. Now when we start a game, a game freezes first. Clicking on it or pressing a space key will unfreeze it. On the frozen screen, we could show an instruction on how to play the game. So at the end of the draw function, ask if the freeze is true, then add a text. Press the space key or click to jump. x is half of the width. y is 70% of the screen height. Make it centred by using the textAlign, CENTER, CENTER, and that's it. In the next video, we will talk about how to share it. Thank you. 12. Share: When you're happy with the result, let's share the final game. To get a sharable link, first, make sure that you logged in, and the project is saved. Then go to File -> Share. Use the full screen link if you want others to see the code behind it. Use the present link to get a standalone game. Or an embedded iFrame to add it to your website. To learn more about p5.js, check out my latest courses in my profile. Please let me know in the comment section, which topics you want to learn more. Thank you.