Build Flappy Bird

Processing Progress
100%

Today we are going to be creating a game called Flappy Bird! I’m sure a lot of you have already seen this game. If not, below is an example

The bird character in our version is a bit abstract, but the rest of it looks pretty much identical to the real Flappy Bird game.

Rules of Flappy Bird

Before we start coding, let’s look at some of the rules of Flappy Bird.

  • The user controls the bird’s vertical position by tapping the screen, in order to navigate the bird through the pipes
  • If the bird hits the pipe, it dies and the game restarts
  • If the bird hits the floor, it dies and the game restarts

Starter Code

You can find the starter code for Flappy Bird here. Open it and copy and paste the code into Processing. You will notice several parts. Let’s walk through them.

Before Setup

You will notice this huge block of code.

gravity = 2
xPos = 50
yPos = 250
birdWidth = 20
birdHeight = 20
minHeight = 50
pipeWidth = 50
pipeXPos = 500
heightTopPipe = 200
heightBottomPipe = 200
spaceBetweenPipes = 100
pipePassed = True
stopGame = False
f = None

The block of code initializes the variables we will need. They are outside of the setup function because they are global variables (used throughout the rest of the code). Please do not modify ANY of these variables. Once you have gotten pong to start working, then you can fiddle around with the values, but until then, leave them alone.

Variable Deep Dive

Gravity Variable

gravity = 2

The gravity variable controls how fast the bird will fall to the ground, we can fiddle with this variable later. We will be using this variable to have the bird fall.

Bird Position Variables

xPos = 50
yPos = 250

This is the original position of the bird. The xPos will always be the same, but we will get the bird’s yPos to change in response to keyboard events.

Bird Shape Variables

birdWidth = 20
birdHeight = 20

These two variables control the size of the bird. They should not be changed in any part of the code, but they will be used to draw the bird (as an ellipse).

Pipe Position and Dimension Variables

minHeight = 50
pipeWidth = 50
pipeXPos = 500

These variables control the pipe’s position and dimensions. The minHeight variable sets the minimum height of the pipe to 50 pixels. The pipeWidth variable controls the width of the pipe. The pipeXPos variable is the starting position of the pipe.

In order to mimic the motion of the bird moving from the left to the right side of the screen, we’ll actually keep the bird’s xPos constant and instead move the pipes from right to left by changing pipeXPos. This will make it look like the bird is moving from left to right, even though in reality the pipes are moving from right to left.

heightTopPipe = 200
heightBottomPipe = 200
spaceBetweenPipes = 100

These variables will control the height of the top and bottom pipe. We’ll want to create a new set of pipes each time a set of pipes passes by the view window, with a different, randomized height for the top and bottom pipe.

To make these pipes with randomized gaps, we’ll write code to call the pipeCreate() function to reassign a random value to heightTopPipe each time the existing set of pipes has passed the view window. heightBottomPipe can be calculated from heightTopPipe and the system variable height, which stores the height of the view window. You can read more about the height variable here. You do not need to worry about altering the height variable, but you can use the value held in it.

Boolean Variables

pipePassed = True
stopGame = False

These variables initialize boolean values for boolean variables, pipePassed and stopGame. Recall that boolean variables can hold only True and False values. You’ll be flipping between these two values by checking for various conditions throughout your code. They will control when pipeCreate() is called and when the view window will display the game over screen.

Font Variable

f = None

This variable holds an initial state for the font variable. It will hold a font object after setup() is called. You do not need to alter this variable, since it is only used for the game over screen. The code for displaying the game over screen has already been implemented for you.

Setup

Let’s look at the code for the setup function. Recall, the code in the setup function runs only once, at the start of the program.

def setup():
    global f
    size(400, 500)
    f = createFont("Arial", 16)

Nothing too exciting, this code just sets up the screen, as we’ve done before. The f variable that creates a font may be somewhat new to you. Do not worry about it too much for now. It will be used to print text on the game over screen.

Draw

Now let’s look at the code for the draw function, which we’ve previously referred to as a draw loop as well. Recall, the code in the draw function repeats over and over again, like an “infinite” loop.

def draw():
    global yPos,stopGame,f
    background(125, 236, 248)
    if stopGame == False:
        moveBird()
        pipeMove()
        endGame()
    else:
        textFont(f, 16)            
        fill(0)                                                
        text("You lost, press shift to start again",10,100)
        if keyPressed: 
            if keyCode == SHIFT:
                stopGame = False

What is this?? There is so many lines! Let’s breakdown the lines.

Global Variables

global yPos, stopGame, f

These two lines, reference the global variables inside the draw function. Anytime you want to assign a new value/update a global variable from within a function, you must declare

global variable_name 

in the function before doing so.

Want a refresher on global variables? Look back at Lesson 2: Events and Movement or talk to a mentor!

Background

background(125, 236, 248)

The line above changes the background color.

Movement

if stopGame == False:
        moveBird()
        pipeMove()
        endGame()

If the game is supposed to continue, it will. This line moves the bird and the pipe but also checks to see if the game is supposed to end.

Game Over Screen

else:
        textFont(f, 16)            
        fill(0)                                                
        text("You lost, press shift to start again", 10, 100)
        if keyPressed: 
            if keyCode == SHIFT:
                stopGame = False

This line deals with what should happen when the game ends. It controls what is displayed on the game over screen.

Functions to Complete

In this section, we’ll be talking about the code you need to write into the remaining functions. Currently, they are just empty functions we’ve defined for you to fill with code.

We put pass in some of these functions, which allows for your code to run even when the function is empty. You’ll want to remove them from your functions as you fill them in.

pipeCreate()

We want this function to create the pipes.

We’ll start by doing a little bit of math. We want the hole between the pipes to be 100 pixels. We also want both the top pipe and the bottom pipe to be at least 50 pixels tall. So, we’ll write some code to assign the top pipe a random height value.

spaceBetweenPipes = 100
maxHeightTopPipe = height - spaceBetweenPipes - minHeight
heightTopPipe = random(minHeight, maxHeightTopPipe)

This piece of code randomizes the height for the top pipe. Now that I have given you the code for this part, let’s make the bottom pipe.

The bottom pipe’s math is a bit easier. Keep in mind we should have the height of the top pipe and the space in between, so it’s just a matter of using math to find the height of the bottom pipe using heightTopPipe, spaceBetweenPipes, and height.

pipeMove()

We want the pipe to move to the left. So, we to change the x position and move the pipe to the left. You’ll want to change the value of pipeXPos to do so.

Tips

pipePass()

This section checks to see if the pipe we created has moved all the way to the left, and if it has, we want to create a new pipe. Use the global variable, pipePassed, to keep track of when the pipe is gone.

Tips

  • Try to identify the condition that tells us whether a pipe has passed the right wall. Remember width is the system variable that gives us the width of the view window and pipeXPos and pipeWidth give us information about the pipe’s x position and width.
  • The if statements introduced in the Collision section of Lesson 3: Velocity and Collision may help you.

moveBird()

Moves the flappy bird. Since we have gravity, the bird should fall and should jump if the SHIFT key is pressed.

Tips

  • Review the Keyboard Events section of Lesson 2: Events and Movement.
  • The system variables, keyPressed and keyCode, may be helpful for writing the if statement that detects when the SHIFT key is pressed.

endGame()

If the bird hits the pipe or the ground, the game should end.

Tips

Hints

Key concepts

There are several concepts that are important for building Pong.

One of the trickiest parts of this project is putting together each of the pieces you learned in Lessons 1-3. It might be helpful to isolate certain functionality to break down the project. Try to test individual parts of your code and make sure a function works before you start working on another. For instance, test if pipeMove() is working correctly before implementing pipePass().

Project Extensions

If you finished the game, here are some extensions you can add to your project as an additional challenge!

  • Score system, counting the number of pipes the bird flies through successfully
  • Lives, every time the game resets, take away a life until it is game over
  • Multiple pipes