How To Make Flappy Bird In Python

In this tutorial, we want to discuss a step-by-step guide on How To Make Flappy Bird In Python, which we can learn with the help of source codes.

What is Flappy Bird Game In Python?

Flappy Bird Game In Python was first released as a mobile game where you tap the screen to make the bird fly. If the bird hits the pipes or the edge of the screen, the game is over and the player has to start over.

Building Flappy Bird In Python With Source Code

Here are the steps on How To Code Flappy Bird In Python, which you can learn with the help of source codes.

Step 1: Installing Libraries

We are installing the libraries needed for the project. For our game, we will make random numbers with random. The program will end by using the sys.exit function from the sys module.

In lines 3 and 4, we are importing Pygame and the basic Pygame imports, respectively.

import random
import sys
import pygame
from pygame.locals import *

Step 2: Declaring Global Variables

In this step, we’re setting up global variables for our game. We first set the values for fps (frames per second), screen_width, and screen_height.

We make the screen by giving screen_width and screen_height arguments to the pygame.display.set_mode() function.

Then, we make a ground-y variable that will give us the y-coordinate for our base image and 2 dictionaries, game images, and game sounds, that will hold all of the images and sounds used in the game.

Then, we store the images of the player (the bird), background, pipe, and title in these variables by giving their paths.

FPS = 32
scr_width = 289
scr_height = 511
display_screen_window = pygame.display.set_mode((scr_width, scr_height))
play_ground = scr_height * 0.8
game_image = {}
game_audio_sound = {}
player = 'images/bird.png'
bcg_image = 'images/background.png'
pipe_image = 'images/pipe.png'

You can download here the Images and audios used in flappy bird game:

Step 3: Creating Main Function

Now, let’s make the main function where our game will start, and we’ll use pygame.init to set up all of the pygame modules ().

We also make the fps_clock variable so that we can use the pygame.tick.Clock() function to keep track of the time.

Then, we’ll give our main game window a title and store all the images in a tuple with first, which we’ll assign to the game_images dictionary’s “numbers” key.

We use the paths to the images as arguments to pygame.image.load() and convert_alpha() to change the pixel format of an image, including the alphas for each pixel.

In the same way, we use different keys to add the images of the message, base, pipe, background, player, and title to the dictionary.

We also added an image of a pipe that was turned upside down by using the pygame.transform.rotate() function to turn the image 180 degrees. Then, we use different keys to add the sounds to the game_sounds dictionary.

It’s like what we did with images, but this time we use pygame.mixer.

The paths to the different sounds are given as an argument to the Sound() function, which stores the sounds. Then we start a loop that calls the functions welcomeScreen() and mainGame(), which will be explained in later sections.

if __name__ == "__main__":

    pygame.init()
    time_clock = pygame.time.Clock()
    pygame.display.set_caption('Flappy Bird Game')
    game_image['numbers'] = (
        pygame.image.load('images/0.png').convert_alpha(),
        pygame.image.load('images/1.png').convert_alpha(),
        pygame.image.load('images/2.png').convert_alpha(),
        pygame.image.load('images/3.png').convert_alpha(),
        pygame.image.load('images/4.png').convert_alpha(),
        pygame.image.load('images/5.png').convert_alpha(),
        pygame.image.load('images/6.png').convert_alpha(),
        pygame.image.load('images/7.png').convert_alpha(),
        pygame.image.load('images/8.png').convert_alpha(),
        pygame.image.load('images/9.png').convert_alpha(),
    )

    game_image['message'] = pygame.image.load('images/message.png').convert_alpha()
    game_image['base'] = pygame.image.load('images/base.png').convert_alpha()
    game_image['pipe'] = (pygame.transform.rotate(pygame.image.load(pipe_image).convert_alpha(), 180),
                          pygame.image.load(pipe_image).convert_alpha()
                          )

    # Game sounds
    game_audio_sound['die'] = pygame.mixer.Sound('sounds/die.wav')
    game_audio_sound['hit'] = pygame.mixer.Sound('sounds/hit.wav')
    game_audio_sound['point'] = pygame.mixer.Sound('sounds/point.wav')
    game_audio_sound['swoosh'] = pygame.mixer.Sound('sounds/swoosh.wav')
    game_audio_sound['wing'] = pygame.mixer.Sound('sounds/wing.wav')

    game_image['background'] = pygame.image.load(bcg_image).convert()
    game_image['player'] = pygame.image.load(player).convert_alpha()

Step 4: Creating Welcome Screen Function

Now, we set up the welcomeScreen() function, which will show the game’s welcome screen when the game starts. We start by giving the player, message, and title images their x-coordinate and y-coordinate values.

We chose the arguments by trying them out, and you can change the values to make them work better for you. The x-coordinate of base is also given here.

Then, we start a while loop that will always be True. This starts a loop that won’t stop until the control says “quit.”

Here, we use a for loop and the pygame.event.get() function to look at all the events that happen during the game. Then, we make sure that when the escape key is used to trigger a quit event, the game window closes.

We’ll look at the next condition, which is whether we pressed the up key or the space bar. We’ll leave the function and start the game if the answer is yes.

And if you don’t press any keys or buttons, the welcome screen comes up. We’ll use the screen.blit() function to put the background, message, player, base, and title images in the right places.

Lastly, we will use pygame.display.update() to update our window and fps as an argument to update our clock variable so that it only shows 32 frames per second.

def welcome_main_screen():
    """
    Shows welcome images on the screen
    """

    p_x = int(scr_width / 5)
    p_y = int((scr_height - game_image['player'].get_height()) / 2)
    msgx = int((scr_width - game_image['message'].get_width()) / 2)
    msgy = int(scr_height * 0.13)
    b_x = 0
    while True:
        for event in pygame.event.get():
            # if user clicks on cross button, close the game
            if event.type == QUIT or (event.type == KEYDOWN and event.key == K_ESCAPE):
                pygame.quit()
                sys.exit()

            # If the user presses space or up key, start the game for them
            elif event.type == KEYDOWN and (event.key == K_SPACE or event.key == K_UP):
                return
            else:
                display_screen_window.blit(game_image['background'], (0, 0))
                display_screen_window.blit(game_image['player'], (p_x, p_y))
                display_screen_window.blit(game_image['message'], (msgx, msgy))
                display_screen_window.blit(game_image['base'], (b_x, play_ground))
                pygame.display.update()
                time_clock.tick(FPS)

Step 5: Creating Main Game Function

Now we define our mainGame() function by setting the score variable to 0 and giving the player image and base coordinates again.

Then, we use getRandomPipe(), which we will define later, to make two pipes for blitting on the screen. Then, we make a list of the x and y coordinates of the upper pipes (the ones that are upside down) and lower pipes.

def main_gameplay():
    score = 0
    p_x = int(scr_width / 5)
    p_y = int(scr_width / 2)
    b_x = 0


    n_pip1 = get_Random_Pipes()
    n_pip2 = get_Random_Pipes()


    up_pips = [
        {'x': scr_width + 200, 'y': n_pip1[0]['y']},
        {'x': scr_width + 200 + (scr_width / 2), 'y': n_pip2[0]['y']},
    ]

    low_pips = [
        {'x': scr_width + 200, 'y': n_pip1[1]['y']},
        {'x': scr_width + 200 + (scr_width / 2), 'y': n_pip2[1]['y']},
    ]

    pip_Vx = -4

    p_vx = -9
    p_mvx = 10
    p_mvy = -8
    p_accuracy = 1

    p_flap_accuracy = -8
    p_flap = False

    while True:
        for event in pygame.event.get():
            if event.type == QUIT or (event.type == KEYDOWN and event.key == K_ESCAPE):
                pygame.quit()
                sys.exit()
            if event.type == KEYDOWN and (event.key == K_SPACE or event.key == K_UP):
                if p_y > 0:
                    p_vx = p_flap_accuracy
                    p_flap = True
                    game_audio_sound['wing'].play()

        cr_tst = is_Colliding(p_x, p_y, up_pips,
                              low_pips)
        if cr_tst:
            return


        p_middle_positions = p_x + game_image['player'].get_width() / 2
        for pipe in up_pips:
            pip_middle_positions = pipe['x'] + game_image['pipe'][0].get_width() / 2
            if pip_middle_positions <= p_middle_positions < pip_middle_positions + 4:
                score += 1
                print(f"Your score is {score}")
                game_audio_sound['point'].play()

        if p_vx < p_mvx and not p_flap:
            p_vx += p_accuracy

        if p_flap:
            p_flap = False
        p_height = game_image['player'].get_height()
        p_y = p_y + min(p_vx, play_ground - p_y - p_height)


        for pip_upper, pip_lower in zip(up_pips, low_pips):
            pip_upper['x'] += pip_Vx
            pip_lower['x'] += pip_Vx


        if 0 < up_pips[0]['x'] < 5:
            new_pip = get_Random_Pipes()
            up_pips.append(new_pip[0])
            low_pips.append(new_pip[1])


        if up_pips[0]['x'] < -game_image['pipe'][0].get_width():
            up_pips.pop(0)
            low_pips.pop(0)


        display_screen_window.blit(game_image['background'], (0, 0))
        for pip_upper, pip_lower in zip(up_pips, low_pips):
            display_screen_window.blit(game_image['pipe'][0], (pip_upper['x'], pip_upper['y']))
            display_screen_window.blit(game_image['pipe'][1], (pip_lower['x'], pip_lower['y']))

        display_screen_window.blit(game_image['base'], (b_x, play_ground))
        display_screen_window.blit(game_image['player'], (p_x, p_y))
        d = [int(x) for x in list(str(score))]
        w = 0
        for digit in d:
            w += game_image['numbers'][digit].get_width()
        Xoffset = (scr_width - w) / 2

        for digit in d:
            display_screen_window.blit(game_image['numbers'][digit], (Xoffset, scr_height * 0.12))
            Xoffset += game_image['numbers'][digit].get_width()
        pygame.display.update()
        time_clock.tick(FPS)

Step 6: Creating Random Function

In these steps, we create two modules which are Is_colliding() module and get_Random_Pipes() module.

def is_Colliding(p_x, p_y, up_pipes, low_pipes):
    if p_y > play_ground - 25 or p_y < 0:
        game_audio_sound['hit'].play()
        return True

    for pipe in up_pipes:
        pip_h = game_image['pipe'][0].get_height()
        if (p_y < pip_h + pipe['y'] and abs(p_x - pipe['x']) < game_image['pipe'][0].get_width()):
            game_audio_sound['hit'].play()
            return True

    for pipe in low_pipes:
        if (p_y + game_image['player'].get_height() > pipe['y']) and abs(p_x - pipe['x']) < \
                game_image['pipe'][0].get_width():
            game_audio_sound['hit'].play()
            return True

    return False


def get_Random_Pipes():
    """
    Generate positions of two pipes(one bottom straight and one top rotated ) for blitting on the screen
    """
    pip_h = game_image['pipe'][0].get_height()
    off_s = scr_height / 3
    yes2 = off_s + random.randrange(0, int(scr_height - game_image['base'].get_height() - 1.2 * off_s))
    pipeX = scr_width + 10
    y1 = pip_h - yes2 + off_s
    pipe = [
        {'x': pipeX, 'y': -y1},  # upper Pipe
        {'x': pipeX, 'y': yes2}  # lower Pipe
    ]
    return pipe

Download the Full Source Code

You can visit this site to download the full source code of Flappy Bird for free.

Conclusion

We have completely discussed a step-by-step guide on How To Make Flappy Bird In Python, I hope this Python Game Tutorial will help you a lot.

Leave a Comment