Write the FlappyBird game in Python (full source code)

Write the FlappyBird game in Python (full source code)

Flappy Bird is a very popular game with a simple but very fun gameplay. This article will teach you to implement this classic game using Python.

First, we need to import the necessary libraries and modules. We will use the PyGame library to create game windows, draw game elements, etc. We also need the random module to generate random numbers.

import pygame
import random

pygame.init()

# Set the game window size
WINDOW_WIDTH = 288
WINDOW_HEIGHT = 512

# create game window
WINDOW = pygame.display.set_mode((WINDOW_WIDTH, WINDOW_HEIGHT))
pygame.display.set_caption("Flappy Bird")

# load game resources
Background_IMAGE = pygame.image.load("assets/background.png").convert()
BIRD_IMAGES = [pygame.image.load("assets/bird1.png").convert_alpha(),
               pygame.image.load("assets/bird2.png").convert_alpha(),
               pygame.image.load("assets/bird3.png").convert_alpha()]
PIPE_IMAGE = pygame.image.load("assets/pipe.png").convert_alpha()
FONT = pygame.font.Font("assets/font.ttf", 36)

Next, we need to define some constants and variables. These constants and variables are needed for the position, velocity, etc. of the different elements in the game. We use UPPER_PIPE_Y to represent the y-coordinate of the top of the upper pipe, and LOWER_PIPE_Y to represent the y-coordinate of the bottom of the lower pipe. BIRD_X and BIRD_Y represent the x-coordinate and y-coordinate of the bird, respectively.

# define constants and variables
FPS = 60
GRAVITY = 1.5
BIRD_X = 50
BIRD_Y = 200
BIRD_SPEED = 0
UPPER_PIPE_Y = -320
LOWER_PIPE_Y = 220
PIPE_GAP = 140
PIPE_SPEED=4

Now we can create the game loop. In the game loop, we first handle game events. If the player presses the space bar, we need to make the bird fly up a certain distance. We also need to update the bird’s position and velocity, and check if the bird collided with the pipe or went out of bounds. If the bird collides with the pipe or goes out of bounds, it’s game over. Finally, we need to draw all the game elements in the game window.

# game loop
while True:
    # Handle game events
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame. quit()
            sys. exit()
        elif event.type == pygame.KEYDOWN:
            if event.key == pygame.K_SPACE:
                BIRD_SPEED = -10

    # Update bird position and velocity
    BIRD_SPEED += GRAVITY
    BIRD_Y += BIRD_SPEED

    # Check if the bird collides with the pipe or goes out of bounds
    if BIRD_Y < 0 or BIRD_Y > WINDOW_HEIGHT - 40:
        print("Game over!")
        pygame. quit()
        sys. exit()

    # draw game elements
    WINDOW.blit(BACKGROUND_IMAGE, (0, 0))
    WINDOW.blit(BIRD_IMAGES[0], (BIRD_X, BIRD_Y))
    pygame.display.update()

We’ve now created the game loop and handled the spacebar events, updating the bird’s position and velocity. Next we need to add the pipeline element. We will use the pipes list to store the pipe objects. Each pipe object has two parts, an upper pipe and a lower pipe. We first randomly generate a y coordinate value, and then calculate the position and size of the upper and lower pipes based on the y coordinate value.

# add pipeline element
class Pipe:
    def __init__(self):
        self.x = WINDOW_WIDTH
        self.y = random.randint(-200, 100)
        self.upper_pipe_rect = PIPE_IMAGE.get_rect(midbottom=(self.x, self.y))
        self.lower_pipe_rect = PIPE_IMAGE.get_rect(midtop=(self.x, self.y + PIPE_GAP))

    def update(self):
        self.x -= PIPE_SPEED
        self.upper_pipe_rect.centerx = self.x
        self.lower_pipe_rect.centerx = self.x

        if self.x < -PIPE_IMAGE.get_width() / 2:
            pipes. remove(self)

def create_pipe():
    pipe = Pipe()
    pipes.append(pipe)

We also need to maintain a pipes list to store all pipe objects. In the game loop, we need to update and draw the pipes in the pipes list. If a pipeline object is out of window bounds, we need to remove it from the list. We also need to periodically create new pipeline elements.

# Define the pipeline list
pipes = []

# create pipeline
create_pipe()
pipe_create_event = pygame.USEREVENT + 1
pygame.time.set_timer(pipe_create_event, 2000)

# main loop
while True:
    # Handle game events
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame. quit()
            sys. exit()
        elif event.type == pygame.KEYDOWN:
            if event.key == pygame.K_SPACE:
                BIRD_SPEED = -10
        elif event.type == pipe_create_event:
            create_pipe()

    # Update bird position and velocity
    BIRD_SPEED += GRAVITY
    BIRD_Y += BIRD_SPEED

    # Check if the bird collides with the pipe or goes out of bounds
    bird_rect = BIRD_IMAGES[0].get_rect(center=(BIRD_X, BIRD_Y))
    for pipe in pipes:
        if bird_rect.colliderect(pipe.upper_pipe_rect) or bird_rect.colliderect(pipe.lower_pipe_rect):
            print("Game over!")
            pygame. quit()
            sys. exit()

    if BIRD_Y < 0 or BIRD_Y > WINDOW_HEIGHT - 40:
        print("Game over!")
        pygame. quit()
        sys. exit()

    # Update pipe positions and remove pipes that are outside the window
    for pipe in pipes:
        pipe. update()

    # draw game elements
    WINDOW.blit(BACKGROUND_IMAGE, (0, 0))
    for pipe in pipes:
        WINDOW.blit(PIPE_IMAGE, pipe.upper_pipe_rect)
        WINDOW.blit(pygame.transform.flip(PIPE_IMAGE, False, True), pipe.lower_pipe_rect)
    WINDOW.blit(BIRD_IMAGES[0], (BIRD_X, BIRD_Y))
    pygame.display.update()
    # set the frame rate
    CLOCK.tick(FPS)

Finally, we display the score at the end of the game. We calculate the score based on the number of birdies that pass through the pipe.

# display score
score = 0

def update_score():
    global score
    for pipe in pipes:
        if pipe.x + PIPE_IMAGE.get_width() < BIRD_X and not pipe.scored:
            score + = 1
            pipe.scored = True

while True:
    # Handle game events
    for event in pygame.event.get():
        ...
    # Update bird position and velocity
    ...
    # Check if the bird collides with the pipe or goes out of bounds
    ...
    # Update pipe positions and remove pipes that are outside the window
    ...
    # draw game elements
    ...
    # show score
    update_score()
    score_surface = FONT. render(str(score), True, (255, 255, 255))
    score_rect = score_surface.get_rect(center=(WINDOW_WIDTH / 2, 50))
    WINDOW.blit(score_surface, score_rect)
    pygame.display.update()
    # set the frame rate
    ...

Full source code:

import pygame
import random
import sys

pygame.init()

# Set the game window size
WINDOW_WIDTH = 288
WINDOW_HEIGHT = 512

# create game window
WINDOW = pygame.display.set_mode((WINDOW_WIDTH, WINDOW_HEIGHT))
pygame.display.set_caption("Flappy Bird")

# load game resources
Background_IMAGE = pygame.image.load("assets/background.png").convert()
BIRD_IMAGES = [pygame.image.load("assets/bird1.png").convert_alpha(),
               pygame.image.load("assets/bird2.png").convert_alpha(),
               pygame.image.load("assets/bird3.png").convert_alpha()]
PIPE_IMAGE = pygame.image.load("assets/pipe.png").convert_alpha()
FONT = pygame.font.Font("assets/font.ttf", 36)

# define constants and variables
FPS = 60
GRAVITY = 1.5
BIRD_X = 50
BIRD_Y = 200
BIRD_SPEED = 0
UPPER_PIPE_Y = -320
LOWER_PIPE_Y = 220
PIPE_GAP = 140
PIPE_SPEED=4

# add pipeline element
class Pipe:
    def __init__(self):
        self.x = WINDOW_WIDTH
        self.y = random.randint(-200, 100)
        self.upper_pipe_rect = PIPE_IMAGE.get_rect(midbottom=(self.x, self.y))
        self.lower_pipe_rect = PIPE_IMAGE.get_rect(midtop=(self.x, self.y + PIPE_GAP))
        self. scored = False

    def update(self):
        self.x -= PIPE_SPEED
        self.upper_pipe_rect.centerx = self.x
        self.lower_pipe_rect.centerx = self.x

        if self.x < -PIPE_IMAGE.get_width() / 2:
            pipes. remove(self)

def create_pipe():
    pipe = Pipe()
    pipes.append(pipe)

# Define the pipeline list
pipes = []

# create pipeline
create_pipe()
pipe_create_event = pygame.USEREVENT + 1
pygame.time.set_timer(pipe_create_event, 2000)

# show score
score = 0

def update_score():
    global score
    for pipe in pipes:
        if pipe.x + PIPE_IMAGE.get_width() < BIRD_X and not pipe.scored:
            score + = 1
            pipe.scored = True

# main loop
CLOCK = pygame. time. Clock()
while True:
    # Handle game events
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame. quit()
            sys. exit()
        elif event.type == pygame.KEYDOWN:
            if event.key == pygame.K_SPACE:
                BIRD_SPEED = -10
        elif event.type == pipe_create_event:
            create_pipe()

    # Update bird position and speed
    BIRD_SPEED += GRAVITY
    BIRD_Y += BIRD_SPEED

    # Check if the bird collides with the pipe or goes out of bounds
    bird_rect = BIRD_IMAGES[0].get_rect(center=(BIRD_X, BIRD_Y))
    for pipe in pipes:
        if bird_rect.colliderect(pipe.upper_pipe_rect) or bird_rect.colliderect(pipe.lower_pipe_rect):
            print("Game over!")
            pygame. quit()
            sys. exit()

    if BIRD_Y < 0 or BIRD_Y > WINDOW_HEIGHT - 40:
        print("Game over!")
        pygame. quit()
        sys. exit()

    # Update pipe positions and remove pipes that are outside the window
    for pipe in pipes:
        pipe. update()

    # Draw game elements
    WINDOW.blit(BACKGROUND_IMAGE, (0, 0))
    for pipe in pipes:
        WINDOW.blit(PIPE_IMAGE, pipe.upper_pipe_rect)
        WINDOW.blit(pygame.transform.flip(PIPE_IMAGE, False, True), pipe.lower_pipe_rect)
    WINDOW.blit(BIRD_IMAGES[0], (BIRD_X, BIRD_Y))
    pygame.display.update()

    # show score
    update_score()
    score_surface = FONT. render(str(score), True, (255, 255, 255))
    score_rect = score_surface.get_rect(center=(WINDOW_WIDTH / 2, 50))
    WINDOW.blit(score_surface, score_rect)

    # set the frame rate
    CLOCK.tick(FPS)