Creating Flappy Bird with pygame. Part - 0

pulimoodan

Akbar Ali

Posted on August 5, 2022

Creating Flappy Bird with pygame. Part - 0

Introduction

I am making the famous Flappy bird game using python and it's library called 'pygame'. It is so simple to make and much addictive to play. It requires only 200 lines of codes. There is a web version of this game you can find at flappybird.io.

About flappy

Flappy Bird was a mobile game developed by Vietnamese video game artist and programmer Dong Nguyen (Vietnamese: Nguyễn Hà Đông), under his game development company, Gears. The game is a side-scroller where the player controls a bird, attempting to fly between columns of green pipes without hitting them. Nguyen created the game over the period of several days, using a bird protagonist that he had designed for a cancelled game in 2012.

Pygame

pygame is a Python wrapper for the SDL library, which stands for Simple DirectMedia Layer. SDL provides cross-platform access to your system’s underlying multimedia hardware components, such as sound, video, mouse, keyboard, and joystick. pygame started life as a replacement for the stalled PySDL project. The cross-platform nature of both SDL and pygame means you can write games and rich multimedia Python programs for every platform that supports them!

Install pygame using pip if you have already installed python.

pip install pygame
Enter fullscreen mode Exit fullscreen mode

Import it into your python program and intialize

import pygame
pygame.init()
Enter fullscreen mode Exit fullscreen mode

Project

Create a project folder named flappy and create a python file named flappy.py in it.

Assets

We need some sprite assets to make this game. The 3 bird sprites with animated wings, the green pipes, ground, background and the restart button. You can find the assets here
download the assets and keep it in a folder named img.
So the file structure would look like this.

flappy
|
| -- img
      |
      -- bg.png
      -- bird1.png
      -- bird2.png
      -- bird3.png
      -- ground.png
      -- pipe.png
      -- restart.png
|
| -- flappy.py
Enter fullscreen mode Exit fullscreen mode

Basic setup

start you code by importing required modules.

import pygame
from pygame.locals import *
import random
Enter fullscreen mode Exit fullscreen mode

pygame.locals module contains various constants used by pygame. We use random for generating random pipes through the sidescroller.

Initialize pygame

pygame.init()
Enter fullscreen mode Exit fullscreen mode

Define screen height and width so we can create the window.

screen_width = 460
screen_height = 500

screen = pygame.display.set_mode((screen_width, screen_height))
pygame.display.set_caption('Flappy Bird')
Enter fullscreen mode Exit fullscreen mode

And finally we need a game loop to run until the player exits.

run = True
while run:
   pass
Enter fullscreen mode Exit fullscreen mode

Make sure to quit pygame at the end of the code

pygame.quit()
Enter fullscreen mode Exit fullscreen mode

Now run the python program from your terminal.

python3 flappy.py
Enter fullscreen mode Exit fullscreen mode

This will open a new blank window with the height and width we defined before. But now we cannot close the window except we interrupt the terminal. This is because we did not instruct the loop to break when the user closes the window and it will trigger the pygame.quit() at the end of the code.

We have to loop through the pygame events and check if it's a closing event. Then make the run to false which will break the loop.

for event in pygame.event.get():
        if event.type == pygame.QUIT:
            run = False
Enter fullscreen mode Exit fullscreen mode

Now we will be able to close the window after running the program.

Background

Let's draw the background first. So import the bg sprite from the img folder and scale it according to the screen.

bg = pygame.image.load('img/bg.png')
bg = pygame.transform.scale(bg, (460, 420))
Enter fullscreen mode Exit fullscreen mode

And inside the loop draw the bg using blit function

# draw background
screen.blit(bg, (0,0))
Enter fullscreen mode Exit fullscreen mode

also add the update function at the end of the loop

pygame.display.update()
Enter fullscreen mode Exit fullscreen mode

Run the program now and you will see the background.
Screen with background

Ground

Import the ground image as we imported the background.

ground_img = pygame.image.load('img/ground.png')
ground_img = pygame.transform.scale(ground_img, (480, 80))
Enter fullscreen mode Exit fullscreen mode

Also declare some variables to make the ground scroll.

# game variables
ground_scroll = 0
scroll_speed = 2
Enter fullscreen mode Exit fullscreen mode

Inside the loop, right after drawing the ground draw the ground with ground_scroll as it's x value. Also update the ground_scroll with scroll_speed.

# draw ground
screen.blit(ground_img, (ground_scroll, 420))
ground_scroll -= scroll_speed
Enter fullscreen mode Exit fullscreen mode

And we also need to reset the ground ground_scroll to 0 after it passes 20 to get a continuous scroll.

if abs(ground_scroll) > 20:
        ground_scroll = 0
Enter fullscreen mode Exit fullscreen mode

FPS

Now the ground scrolls so fast and we have to control the fps. Otherwise fps may vary from computers to computers. So at the top, declare fps and pygame clock

# fps control
clock = pygame.time.Clock()
fps = 60
Enter fullscreen mode Exit fullscreen mode

Inside the loop, at the top call the tick function using fps variable.

clock.tick(fps)
Enter fullscreen mode Exit fullscreen mode

Try the game and see the ground scrolls slowly.

Bird class

Now, let's create the bird class. In the bird class, we have a constructor where we receive the x, y and an update method.

class Bird(pygame.sprite.Sprite):
    def __init__(self, x, y):
        pass

    def update(self):
        pass

Enter fullscreen mode Exit fullscreen mode

See we have derived the class from pygame.sprite.Sprite. It's a simple base class for visible game objects.
Let's code the __init__ method.

def __init__(self, x, y):
        pygame.sprite.Sprite.__init__(self)
        self.images = []
        self.index = 0
        self.counter = 0
        for num in range(1, 4):
            img = pygame.image.load(f'img/bird{num}.png')
            img = pygame.transform.scale(img, (35, 25))
            self.images.append(img)
        self.image = self.images[self.index]
        self.rect = self.image.get_rect()
        self.rect.center = [x, y]
        self.vel = 0
        self.clicked = False
Enter fullscreen mode Exit fullscreen mode

Here we called the constructor of pygame.sprite.Sprite at first. We have 3 sprites of bird images to animate. So, we loop 3 times and store each images to the images[]. The index variable is used to get the nth images at each frame. counter is to control the animation fps. Also, we center the image to the x, y using the rect of the sprite. vel is to set the velocity of the bird when the clicked = true.

Now, we have the update method to code.

def update(self):

        # gravity
        if flying == True:
            self.vel += 0.2
            if self.vel > 30:
                self.vel = 0
            if self.rect.bottom < 420:
                self.rect.y += int(self.vel)
Enter fullscreen mode Exit fullscreen mode

We coded the gravity functionality for the bird first. Make sure we have declared the flying variable at the top of the code.

flying = False
Enter fullscreen mode Exit fullscreen mode

We will add the velocity by 0.2 while the bird is flying and clamped the value to 30 because the bird don't need to go below the ground. The vel variable will be added to rect.y which leads to bring the bird downward like it's falling down.

Then, declare a game_over variable at the top and append this code to the update method.

if game_over == False:
            # jump
            if pygame.mouse.get_pressed()[0] == 1 and self.clicked == False:
                self.clicked = True
                self.vel = -5
            if pygame.mouse.get_pressed()[0] == 0:
                self.clicked = False
Enter fullscreen mode Exit fullscreen mode

Check if it's not game over and the bird have to jump when the mouse pressed. We don't need to get continuous clicks, so we have to check the self.clicked is false. It it's time to jump, we set clicked to true and vel to -5 which leads the bird upwards. We set the clicked to false when the mouse is released.

Now we have to animate the bird.

            # handle animation
            self.counter += 1
            flap_cooldown = 5

            if self.counter > flap_cooldown:
                self.counter = 0
                self.index += 1
                if self.index >= len(self.images):
                    self.index = 0

            self.image = self.images[self.index]
Enter fullscreen mode Exit fullscreen mode

We set a variable flap_cooldown to 5 and will check if the counter goes after it. Then, change the index variable and update the sprite image according to the index. Make sure that index is not greater than the length of the images. If it is, set it to 0.

At last, we will rotate the bird according to the velocity.

# rotate the bird
            self.image = pygame.transform.rotate(self.images[self.index], self.vel * -2)
Enter fullscreen mode Exit fullscreen mode

Make sure the above all codes are indented inside the game_over == False condition. And when the game_over == true we have to point the bird down like it's falling down quickly. So, right after the above condition, code this.

else:
     self.image = pygame.transform.rotate(self.images[self.index], -90)
Enter fullscreen mode Exit fullscreen mode

Now, our bird class is complete. let's draw the bird inside the loop. But, before that, we have to create a class group of bird right above the loop.

bird_group = pygame.sprite.Group()
Enter fullscreen mode Exit fullscreen mode

And add a new Bird object to the group.

flappy = Bird(100, int(screen_height/2))
bird_group.add(flappy)
Enter fullscreen mode Exit fullscreen mode

We do this because it's easy to draw the sprite.Group class of pygame because it has a default draw method itself.

Jump into the loop and call the draw and update method of the bird group.

# draw bird
bird_group.draw(screen)
bird_group.update()
Enter fullscreen mode Exit fullscreen mode

Make sure we put this code after drawing the bg and ground, because we need the bird at the top of them.

Also add this code in the for event in pygame.event.get() loop to make the flying = true.

if event.type == pygame.MOUSEBUTTONDOWN and flying == False and game_over == False:
            flying = True
Enter fullscreen mode Exit fullscreen mode

This will trigger the bird to fly when we click the mouse button for the first time. But won't start the game when open it.
One more update to do. we have to cover the ground_scroll update we coded before inside a condition, because we don't have to scroll the ground if the game is not started yet.

if game_over == False and flying == True:
        # scroll ground
        ground_scroll -= scroll_speed
        if abs(ground_scroll) > 20:
            ground_scroll = 0
Enter fullscreen mode Exit fullscreen mode

Now everything will start moving after we click the mouse button for the first time. Try the game now.

Conclusion

Hope you loved this post and enjoyed making flappy together. I will get back to you soon with another post where we add more functionalities to the game. Comment your opinions and doubts.

Second part: Part-1

Buy Me A Coffee

💖 💪 🙅 🚩
pulimoodan
Akbar Ali

Posted on August 5, 2022

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related