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 pipeDownload the Full Source Code
You can visit this site to download the full source code of Flappy Bird for free.
Frequently Asked Questions
How do you play this Python Flappy Bird clone?
Press Spacebar (or click) to make the bird flap upward against gravity. Gravity pulls the bird down continuously. Pipes scroll right to left at a constant speed. Navigate the bird through the gaps without touching any pipe or the ground. Each pipe passed adds 1 to the score. Hitting any pipe, the top of the screen, or the ground ends the game. Difficulty is set by GAP_HEIGHT and PIPE_SPEED constants near the top of the file.
What Python version do I need to run this game?
Python 3.8 or newer works. We recommend Python 3.11 or 3.12 because Pygame ships pre-built wheels for those versions (faster pip install, no compilation errors). Python 3.13 may need a slightly older Pygame release because some wheels lag the latest CPython. Verify your version with python –version on Windows or python3 –version on Mac/Linux.
How do I install Pygame for this project?
Run pip install pygame in your terminal (Windows: open Command Prompt, Mac/Linux: open Terminal). On Windows, if pip is not recognized, try python -m pip install pygame instead. On Linux, you may need sudo apt install python3-pygame if pip fails. Verify with python -c “import pygame; print(pygame.version.ver)”.
Can I use this Python game as my BSIT capstone project?
On its own, no, most Philippine BSIT panels expect a full system with users, data, reports, and a real-world problem. A single Pygame game is too narrow for capstone scope. BUT, you can use this game as ONE module inside a larger capstone (e.g. a gamified learning system, a math practice tool for elementary students with this game as the reward layer, or an arcade-style POS for an internet cafe). Pair the game with a Django backend, a database, and analytics for a defensible capstone.
Can I package this game as a standalone .exe to distribute?
Yes, use PyInstaller. Run pip install pyinstaller then pyinstaller –onefile –windowed your_game.py from the project folder. PyInstaller bundles Python and Pygame into a single .exe (Windows) or .app (Mac) that runs without Python installed on the target machine. Include asset files (images, sounds) with –add-data “assets;assets”. Output goes to the dist/ folder.
Where do I get help if the game does not run?
Check the top 3 most common failures: (1) Pygame is not installed correctly, re-run pip install pygame. (2) The game cannot find an asset file (image/sound), make sure you run python from the project folder so relative paths resolve. (3) Wrong Python version, this code expects Python 3.8+; older Python 2.x or 3.6 raises syntax errors. If you still hit a wall, drop a comment on this article with the exact error message, our team monitors comments daily.
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.
