In this article, we will explore how to create a Flappy Bird game using Pygame.
We all know and love this game. The main objective is for the player to score the highest points by guiding the bird through obstacles. Here, we’ll build our very own Flappy Bird game with Python.
We’ll be using Pygame, a Python library specifically designed for making video games. Pygame is an open-source library that helps us create fully functional games and multimedia programs in Python.
First, you need to install the Pygame library using the command:
pip install pygame
Let’s get started
copy the code below and paste it in your code editor

Full Code:
import pygame, random, time
from pygame.locals import *
#VARIABLES
SCREEN_WIDHT = 400
SCREEN_HEIGHT = 600
SPEED = 20
GRAVITY = 2.5
GAME_SPEED = 15
GROUND_WIDHT = 2 * SCREEN_WIDHT
GROUND_HEIGHT= 100
PIPE_WIDHT = 80
PIPE_HEIGHT = 500
PIPE_GAP = 150
wing = 'wing.wav'
hit = 'hit.wav'
pygame.mixer.init()
class Bird(pygame.sprite.Sprite):
def __init__(self):
pygame.sprite.Sprite.__init__(self)
self.images = [pygame.image.load('bluebird-upflap.png').convert_alpha(),
pygame.image.load('bluebird-midflap.png').convert_alpha(),
pygame.image.load('bluebird-downflap.png').convert_alpha()]
self.speed = SPEED
self.current_image = 0
self.image = pygame.image.load('bluebird-upflap.png').convert_alpha()
self.mask = pygame.mask.from_surface(self.image)
self.rect = self.image.get_rect()
self.rect[0] = SCREEN_WIDHT / 6
self.rect[1] = SCREEN_HEIGHT / 2
def update(self):
self.current_image = (self.current_image + 1) % 3
self.image = self.images[self.current_image]
self.speed += GRAVITY
#UPDATE HEIGHT
self.rect[1] += self.speed
def bump(self):
self.speed = -SPEED
def begin(self):
self.current_image = (self.current_image + 1) % 3
self.image = self.images[self.current_image]
class Pipe(pygame.sprite.Sprite):
def __init__(self, inverted, xpos, ysize):
pygame.sprite.Sprite.__init__(self)
self. image = pygame.image.load('pipe-green.png').convert_alpha()
self.image = pygame.transform.scale(self.image, (PIPE_WIDHT, PIPE_HEIGHT))
self.rect = self.image.get_rect()
self.rect[0] = xpos
if inverted:
self.image = pygame.transform.flip(self.image, False, True)
self.rect[1] = - (self.rect[3] - ysize)
else:
self.rect[1] = SCREEN_HEIGHT - ysize
self.mask = pygame.mask.from_surface(self.image)
def update(self):
self.rect[0] -= GAME_SPEED
class Ground(pygame.sprite.Sprite):
def __init__(self, xpos):
pygame.sprite.Sprite.__init__(self)
self.image = pygame.image.load('base.png').convert_alpha()
self.image = pygame.transform.scale(self.image, (GROUND_WIDHT, GROUND_HEIGHT))
self.mask = pygame.mask.from_surface(self.image)
self.rect = self.image.get_rect()
self.rect[0] = xpos
self.rect[1] = SCREEN_HEIGHT - GROUND_HEIGHT
def update(self):
self.rect[0] -= GAME_SPEED
def is_off_screen(sprite):
return sprite.rect[0] < -(sprite.rect[2])
def get_random_pipes(xpos):
size = random.randint(100, 300)
pipe = Pipe(False, xpos, size)
pipe_inverted = Pipe(True, xpos, SCREEN_HEIGHT - size - PIPE_GAP)
return pipe, pipe_inverted
pygame.init()
screen = pygame.display.set_mode((SCREEN_WIDHT, SCREEN_HEIGHT))
pygame.display.set_caption('Flappy Bird')
BACKGROUND = pygame.image.load('background-day.png')
BACKGROUND = pygame.transform.scale(BACKGROUND, (SCREEN_WIDHT, SCREEN_HEIGHT))
BEGIN_IMAGE = pygame.image.load('message.png').convert_alpha()
bird_group = pygame.sprite.Group()
bird = Bird()
bird_group.add(bird)
ground_group = pygame.sprite.Group()
for i in range (2):
ground = Ground(GROUND_WIDHT * i)
ground_group.add(ground)
pipe_group = pygame.sprite.Group()
for i in range (2):
pipes = get_random_pipes(SCREEN_WIDHT * i + 800)
pipe_group.add(pipes[0])
pipe_group.add(pipes[1])
clock = pygame.time.Clock()
begin = True
while begin:
clock.tick(15)
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
if event.type == KEYDOWN:
if event.key == K_SPACE or event.key == K_UP:
bird.bump()
pygame.mixer.music.load(wing)
pygame.mixer.music.play()
begin = False
screen.blit(BACKGROUND, (0, 0))
screen.blit(BEGIN_IMAGE, (120, 150))
if is_off_screen(ground_group.sprites()[0]):
ground_group.remove(ground_group.sprites()[0])
new_ground = Ground(GROUND_WIDHT - 20)
ground_group.add(new_ground)
bird.begin()
ground_group.update()
bird_group.draw(screen)
ground_group.draw(screen)
pygame.display.update()
while True:
clock.tick(15)
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
if event.type == KEYDOWN:
if event.key == K_SPACE or event.key == K_UP:
bird.bump()
pygame.mixer.music.load(wing)
pygame.mixer.music.play()
screen.blit(BACKGROUND, (0, 0))
if is_off_screen(ground_group.sprites()[0]):
ground_group.remove(ground_group.sprites()[0])
new_ground = Ground(GROUND_WIDHT - 20)
ground_group.add(new_ground)
if is_off_screen(pipe_group.sprites()[0]):
pipe_group.remove(pipe_group.sprites()[0])
pipe_group.remove(pipe_group.sprites()[0])
pipes = get_random_pipes(SCREEN_WIDHT * 2)
pipe_group.add(pipes[0])
pipe_group.add(pipes[1])
bird_group.update()
ground_group.update()
pipe_group.update()
bird_group.draw(screen)
pipe_group.draw(screen)
ground_group.draw(screen)
pygame.display.update()
if (pygame.sprite.groupcollide(bird_group, ground_group, False, False, pygame.sprite.collide_mask) or
pygame.sprite.groupcollide(bird_group, pipe_group, False, False, pygame.sprite.collide_mask)):
pygame.mixer.music.load(hit)
pygame.mixer.music.play()
time.sleep(1)
break
Note – If you wish You can download the images from here for the flappy bird game, the ones which i have used.
Output:
Explanation of the whole code:
Importing Libraries: The code starts by importing the necessary libraries: pygame for creating the game, random for generating random numbers, and time for handling time-related tasks.
import pygame, random, time
from pygame.locals import *
Setting Variables: Various game settings are defined, such as screen dimensions, speed, gravity, and dimensions for the ground and pipes.
SCREEN_WIDTH = 400
SCREEN_HEIGHT = 600
SPEED = 20
GRAVITY = 2.5
GAME_SPEED = 15
GROUND_WIDTH = 2 * SCREEN_WIDTH
GROUND_HEIGHT = 100
PIPE_WIDTH = 80
PIPE_HEIGHT = 500
PIPE_GAP = 150
wing = 'wing.wav'
hit = 'hit.wav'
Initializing Pygame’s Mixer: This initializes the sound mixer for playing sound effects.
pygame.mixer.init()
Creating the Bird Class: This class defines the bird’s behavior, such as loading its images, handling its movement, and updating its position based on gravity.
class Bird(pygame.sprite.Sprite):
def __init__(self):
# Initialize the bird sprite
pygame.sprite.Sprite.__init__(self)
self.images = [pygame.image.load('bluebird-upflap.png').convert_alpha(),
pygame.image.load('bluebird-midflap.png').convert_alpha(),
pygame.image.load('bluebird-downflap.png').convert_alpha()]
self.speed = SPEED
self.current_image = 0
self.image = pygame.image.load('bluebird-upflap.png').convert_alpha()
self.mask = pygame.mask.from_surface(self.image)
self.rect = self.image.get_rect()
self.rect[0] = SCREEN_WIDTH / 6
self.rect[1] = SCREEN_HEIGHT / 2
def update(self):
# Update the bird's position and image
self.current_image = (self.current_image + 1) % 3
self.image = self.images[self.current_image]
self.speed += GRAVITY
self.rect[1] += self.speed
def bump(self):
# Make the bird jump
self.speed = -SPEED
def begin(self):
# Update the bird's image at the beginning
self.current_image = (self.current_image + 1) % 3
self.image = self.images[self.current_image]
Creating the Pipe Class: This class defines the pipes that the bird must avoid. It handles loading the pipe images, positioning them, and moving them across the screen.
class Pipe(pygame.sprite.Sprite):
def __init__(self, inverted, xpos, ysize):
# Initialize the pipe sprite
pygame.sprite.Sprite.__init__(self)
self.image = pygame.image.load('pipe-green.png').convert_alpha()
self.image = pygame.transform.scale(self.image, (PIPE_WIDTH, PIPE_HEIGHT))
self.rect = self.image.get_rect()
self.rect[0] = xpos
if inverted:
self.image = pygame.transform.flip(self.image, False, True)
self.rect[1] = - (self.rect[3] - ysize)
else:
self.rect[1] = SCREEN_HEIGHT - ysize
self.mask = pygame.mask.from_surface(self.image)
def update(self):
# Move the pipe leftward
self.rect[0] -= GAME_SPEED
Creating the Ground Class: This class handles the ground’s behavior, including loading the ground image, positioning it, and moving it to create a scrolling effect.
class Ground(pygame.sprite.Sprite):
def __init__(self, xpos):
# Initialize the ground sprite
pygame.sprite.Sprite.__init__(self)
self.image = pygame.image.load('base.png').convert_alpha()
self.image = pygame.transform.scale(self.image, (GROUND_WIDTH, GROUND_HEIGHT))
self.mask = pygame.mask.from_surface(self.image)
self.rect = self.image.get_rect()
self.rect[0] = xpos
self.rect[1] = SCREEN_HEIGHT - GROUND_HEIGHT
def update(self):
# Move the ground leftward
self.rect[0] -= GAME_SPEED
Helper Functions: These functions check if a sprite has moved off the screen and generate random pipes for the game.
def is_off_screen(sprite):
return sprite.rect[0] < -(sprite.rect[2])
def get_random_pipes(xpos):
size = random.randint(100, 300)
pipe = Pipe(False, xpos, size)
pipe_inverted = Pipe(True, xpos, SCREEN_HEIGHT - size - PIPE_GAP)
return pipe, pipe_inverted
Initializing the Game: This section initializes Pygame, sets up the display window, loads the background image, and initializes sprite groups for the bird, ground, and pipes.
pygame.init()
screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
pygame.display.set_caption('Flappy Bird')
BACKGROUND = pygame.image.load('background-day.png')
BACKGROUND = pygame.transform.scale(BACKGROUND, (SCREEN_WIDTH, SCREEN_HEIGHT))
BEGIN_IMAGE = pygame.image.load('message.png').convert_alpha()
Setting Up Sprites: This section creates instances of the Bird, Ground, and Pipe classes, and adds them to their respective sprite groups.
bird_group = pygame.sprite.Group()
bird = Bird()
bird_group.add(bird)
ground_group = pygame.sprite.Group()
for i in range(2):
ground = Ground(GROUND_WIDTH * i)
ground_group.add(ground)
pipe_group = pygame.sprite.Group()
for i in range(2):
pipes = get_random_pipes(SCREEN_WIDTH * i + 800)
pipe_group.add(pipes[0])
pipe_group.add(pipes[1])
Main Game Loop (Begin Screen): This loop displays the starting screen and waits for the player to press a key to start the game.
clock = pygame.time.Clock()
begin = True
while begin:
clock.tick(15)
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
if event.type == KEYDOWN:
if event.key == K_SPACE or event.key == K_UP:
bird.bump() # Make the bird jump
pygame.mixer.music.load(wing)
pygame.mixer.music.play()
begin = False # Exit the begin screen loop
screen.blit(BACKGROUND, (0, 0)) # Draw the background
screen.blit(BEGIN_IMAGE, (120, 150)) # Draw the beginning image
if is_off_screen(ground_group.sprites()[0]):
ground_group.remove(ground_group.sprites()[0])
new_ground = Ground(GROUND_WIDTH - 20)
ground_group.add(new_ground)
bird.begin() # Update bird animation
ground_group.update() # Update ground position
bird_group.draw(screen) # Draw bird
ground_group.draw(screen) # Draw ground
pygame.display.update() # Update the display
Main Game Loop (Gameplay): This is the main game loop where the actual game runs. It handles events, updates game objects, checks for collisions, and renders everything on the screen.
while True:
clock.tick(15)
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
if event.type == KEYDOWN:
if event.key == K_SPACE or event.key == K_UP:
bird.bump() # Make the bird jump
pygame.mixer.music.load(wing)
pygame.mixer.music.play()
screen.blit(BACKGROUND, (0, 0)) # Draw the background
if is_off_screen(ground_group.sprites()[0]):
ground_group.remove(ground_group.sprites()[0])
new_ground = Ground(GROUND_WIDTH - 20)
ground_group.add(new_ground)
if is_off_screen(pipe_group.sprites()[0]):
pipe_group.remove(pipe_group.sprites()[0])
pipe_group.remove(pipe_group.sprites()[0])
pipes = get_random_pipes(SCREEN_WIDTH * 2)
pipe_group.add(pipes[0])
pipe_group.add(pipes[1])
bird_group.update() # Update bird position and animation
ground_group.update() # Update ground position
pipe_group.update() # Update pipes position
bird_group.draw(screen) # Draw bird
pipe_group.draw(screen) # Draw pipes
ground_group.draw(screen) # Draw ground
pygame.display.update() # Update the display
# Check for collisions
if (pygame.sprite.groupcollide(bird_group, ground_group, False, False, pygame.sprite.collide_mask) or
pygame.sprite.groupcollide(bird_group, pipe_group, False, False, pygame.sprite.collide_mask)):
pygame.mixer.music.load(hit)
pygame.mixer.music.play()
time.sleep(1)
break
Explanation of Key Components
- Variables: Constants like
SCREEN_WIDTH,SCREEN_HEIGHT, andSPEEDare defined to set the game’s dimensions and speeds. - Classes:
Bird,Pipe, andGroundclasses handle the game’s main objects, including their images, positions, and movements. - Helper Functions:
is_off_screenchecks if an object is off the screen, andget_random_pipesgenerates random pipes for the bird to navigate through. - Initialization: Pygame is initialized, and the display, background, and sprite groups are set up.
- Begin Screen Loop: This loop displays the start screen and waits for player input to begin the game.
- Main Game Loop: This loop handles the main gameplay, including event handling, updating positions, drawing objects, and checking for collisions.
This code essentially sets up and runs a simple version of the Flappy Bird game, where the player controls a bird that must navigate through gaps between pipes while avoiding the ground and pipes. The game includes basic animations, collision detection, and sound effects.
Creating a Flappy Bird game using Pygame in Python is a fantastic way to delve into game development and enhance your programming skills. By following the steps outlined in this tutorial, you’ve learned how to set up the game environment, manage game sprites, handle user inputs, and implement collision detection. This project not only demonstrates the power of Pygame for creating interactive applications but also provides a solid foundation for developing more complex games in the future. Keep experimenting and have fun as you continue your journey in game development!





Leave a Reply