Creating Flappy Bird with pygame. Part - 0
Tags: gamedev, beginners, python, tutorial
Published: 2022-08-05 02:59:00

## 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](https://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
```

Import it into your python program and intialize

```
import pygame
pygame.init()
```

## 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](https://github.com/pulimoodan/flappy/tree/main/img)
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
```

## Basic setup
start you code by importing required modules.

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

Initialize pygame
```
pygame.init()
```

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')
```

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

```
run = True
while run:
   pass
```

Make sure to quit pygame at the end of the code

```
pygame.quit()
```

Now run the python program from your terminal.

```
python3 flappy.py
```

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
```
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))
```

And inside the loop draw the bg using `blit` function 

```
# draw background
screen.blit(bg, (0,0))
```
also add the update function at the end of the loop

```
pygame.display.update()
```

Run the program now and you will see the background.
![Screen with background](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5u7xpzjyxanl5d5yspbe.png)

## 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))
```
Also declare some variables to make the ground scroll.

```
# game variables
ground_scroll = 0
scroll_speed = 2
```

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
```
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
```

## 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
```

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

```
clock.tick(fps)
```
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

```
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
```
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)
```
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
```
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
```
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]
```
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)
```
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)
```

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()
```
And add a new `Bird` object to the group.

```
flappy = Bird(100, int(screen_height/2))
bird_group.add(flappy)
```
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()
```
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
```
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
```
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](https://dev.to/pulimoodan/creating-flappy-bird-with-pygame-part-1-11kd)

[![Buy Me A Coffee](https://cdn.buymeacoffee.com/buttons/default-black.png)](https://www.buymeacoffee.com/pulimoodan)