Python Flappy Bird AI Tutorial (with NEAT) - Finishing the Graphics

Creating a Game of Flappy Bird: A Step-by-Step Guide

The game of Flappy Bird is a simple yet challenging game that requires precision and timing to play. In this guide, we will walk through the steps to create a basic version of Flappy Bird using Python and the Pygame library.

First, we need to set up our game window. We start by creating a new window with a size of 640x480 pixels. This is the default size for our game window.

```

import pygame

import sys

pygame.init()

screen = pygame.display.set_mode((640, 480))

clock = pygame.time.Clock()

# Define some colors

WHITE = (255, 255, 255)

RED = (255, 0, 0)

class Bird:

def __init__(self):

self.x = 100

self.y = 240

self.width = 20

self.height = 20

bird = Bird()

# Define some constants

screen_width = 640

screen_height = 480

pipe_width = 80

pipe_height = 600

floor_y = screen_height - 50

def draw_floor():

pygame.draw.rect(screen, WHITE, (0, floor_y, screen_width, 50))

def draw_pipe():

pygame.draw.rect(screen, RED, (screen_width // 2 - pipe_width // 2, 0, pipe_width, pipe_height))

```

Next, we need to define our bird's movement. We want the bird to move up and down when the player presses the space bar.

```

def update_bird(bird):

if keys[pygame.K_SPACE] and bird.y > floor_y - bird.height:

bird.y -= 10

if bird.y < 0:

bird.y = 0

keys = pygame.key.get_pressed()

while True:

screen.fill((0, 0, 0))

draw_floor()

update_bird(bird)

```

Now that we have our bird's movement set up, we can start thinking about collision detection. In this game, the bird will need to avoid hitting the ground and the pipes.

```

def check_collision(bird):

if bird.y + bird.height > floor_y:

return True

for pipe in pipes:

if (bird.x < pipe[0] + pipe_width) and (bird.x + bird.width > pipe[0]):

if (bird.y < pipe[1]) or (bird.y + bird.height > pipe[1] + pipe_height):

return True

pipes = [(screen_width // 2 - pipe_width // 2, 100), (screen_width // 2 + pipe_width // 2, 200)]

def update_pipes(pipes):

for i in range(len(pipes) - 1, 0, -1):

pipes[i] = pipes[i-1]

def check_collision_bird(bird, pipes):

return check_collision(bird) or check_collision_bird(bird, pipes)

while True:

screen.fill((0, 0, 0))

draw_floor()

update_bird(bird)

update_pipes(pipes)

for pipe in pipes:

pygame.draw.rect(screen, RED, (pipe[0], 0, pipe_width, pipe_height))

if check_collision_bird(bird, pipes):

print("Game Over")

```

Next, we need to add scoring. We'll display the score at the top of the screen.

```

def draw_score(score):

font = pygame.font.Font(None, 50)

text = font.render(str(score), True, WHITE)

screen.blit(text, (10, 10))

score = 0

while True:

screen.fill((0, 0, 0))

draw_floor()

update_bird(bird)

update_pipes(pipes)

for pipe in pipes:

pygame.draw.rect(screen, RED, (pipe[0], 0, pipe_width, pipe_height))

if check_collision_bird(bird, pipes):

print("Game Over")

score = 0

draw_score(score)

```

Finally, we need to add the AI to our game. We'll use a simple algorithm to move the bird up and down.

```

def update_bird_ai(bird, pipes):

if pipe_y1 < bird.y + bird.height // 2:

bird.y -= 5

elif pipe_y2 < bird.y - bird.height // 2:

bird.y += 5

pipe_y1 = pipes[0][1]

pipe_y2 = pipes[1][1]

while True:

screen.fill((0, 0, 0))

draw_floor()

update_bird_ai(bird, pipes)

update_pipes(pipes)

for pipe in pipes:

pygame.draw.rect(screen, RED, (pipe[0], 0, pipe_width, pipe_height))

if check_collision_bird(bird, pipes):

print("Game Over")

```

This is a basic implementation of Flappy Bird using Python and Pygame. There's still room for improvement, but this should give you a good starting point for creating your own version of the game.

"WEBVTTKind: captionsLanguage: enall right so now let's work in the main game loop and start getting all this to work together so we've successfully completed the bass we've completed the pipe we have the bird now it's just time to implement all of it so first I'm just going to change my draw window function a little bit so now I'm gonna add in an ability to draw pipes as well as the ability to draw the base so what I'm gonna do in here is just complete this already is I'm gonna draw all the pipes and the base so I'm gonna say for pipe in pipes and pipes are get is gonna come in as a list because we could have more than one pipe on a screen at once I'm simply gonna say not that pipe don't draw and we'll pass it a window so now for all of our pipes we will draw them next thing I'm gonna do is say bass drop and give it a window and that's as easy as it is to draw our stuff and that's why I really like creating these draw methods because they just make it super clean and we can do all of the drawing from the object itself all right so next we need to now add and create I guess a bass and some pipes so let's start by first of all just changing our bird position to be a little bit different so I'm gonna change it to actually be 23350 because that's where it should actually be located at least like that's what I figured out is kind of the best position and what I'm also gonna do is create a base now just gonna say base equals base and give this a height of 700 now this is because this is gonna be at the very bottom of our screen and that's where 700 is because I believe the height is 800 let me actually just look here to make sure I'm just looking at my other file by the way because I want to make sure I don't mess any of this up oh my bad actually we're not gonna make it 700 we're going to make it 7:30 it's a little bit lower okay so 730 that's where our base is now we're gonna make sure that we past pipes and base and I guess I need to still program pipes don't ever say say pipes equals a list and I'm just gonna throw one pipe in here right now and we'll start with it at a height of 700 okay so now that we have that this is gonna be weird but we can actually just draw this and see what this looks like to start so let's do control B here and you can see that we now have this base which isn't moving as well as this bird so if we want to fix this and allow it to move well let's do that so let's start by actually moving the base so let's say base don't move like this and now let's run this and see what happens and now you can see we have this moving base and it makes it look like our bird is actually kind of flying through the screen which i think is pretty interesting and that was pretty easy to do alright so now let's move all of our pipes and if we remember here if I go to pipes what do you call it here our pipe yes so it needs to move backwards because we give it a starting exhibition my apologies so anyway so let's now move all of our pipe so do this I'm gonna say four pipe in pipes because we might have more than one pipe in here on a say pipe don't move all right now let's see if we got a pipe moving on our screen all right give it a second and there we go we have some pipes they have a random height and they have started moving so now we need to do is figure out once that pipe kind of leaves the screen we need to generate another one and another one and another one so how do we do that well we're gonna do that inside of this four loop that we just created so what we essentially need to do is check the x position of our pipe and once it reaches certain point we need to create another pipe and then another pipe and then another one and then another one and so on so what I'm gonna do here is first we're actually going to check for collision with our pipes so I'm gonna say if bird are not very I'm saying if pipe dot collide bird then what we'll do is well we need to do something so in this case I'm actually just gonna pass for right now because I don't want to do anything with the bird quite yet but if we collide with the pipe well we need to you know end the game we need to actually do something now the next thing I'm gonna do is check the position of the pipe so I'm gonna say if pipe I go down here if pipe dot x+ pipe pipe underscore I guess whether top dog get underscore width is less than zero now what this essentially is checking is if our pipe is completely off the screen so by getting the x position of the pipe as well as the width of it if it's less than zero that means it's completely the screen then what we're gonna do is we're gonna remove that pipe now we can't quite just remove it from this for loop because we're looping through the pipes so what we need to do is create a list called Rama which is gonna stand for remove and we're gonna add that pipe to the list to remove so we're gonna say Ram dot append pipe and that's pretty straightforward all right now what the next thing we're to do is we're gonna say if not type dot pass and pipe dot X less than bird dot X row and you say type dot past equals true and we're gonna say add underscore pipe equals true now what this is gonna do for us is it's gonna check if we have passed the pipe so let's go back into our drawing thing here and I can't I have now I regret having stopped drawing the thing so anyways let's say that you know this is our pipe like this and let's say that this is our bird well as soon as our bird passes by this pipe what we need to do is generate a new pipe for it to start you know going through or whatever so that's what we're checking there as soon as we pass the pipe generate a new one anyways let's do that now so we say add pipe and then we continue to move these pipes now what I'm gonna do in here is get outside of this for loop and say if add underscore pipe then what we're gonna do is say score plus equals one which reminds me I need to create a score variable because once we pass a pipe well that means that we've gotten a point we need to keep track of that for our game then what we're gonna do is we're gonna create a new pipe I'm gonna add that to the screen so to do that is pretty straightforward we're gonna say pipes u dot append and in this case we're just gonna do pipe and we're gonna give it the same x position of 700 now after we do this we're going to remove those pipes that we had up here that we need to remove because they went off the screen I'm gonna say for our in in REM let us say pipes don't remove our and that should just get rid of our pipes for us alright so now that we have that we actually will see that our pipes will start generating properly on the screen so let's run this clicking the wrong key here what is my variable local add piped reference oh my bad we need to do ad underscore pipe equals false to start up here because you know if this doesn't happen we're not gonna define it so just make sure you add that at the top above remove let's run this and now we should see that our pipes start generating and as soon as we pass one pipe another pipe will generate hmm what is the air here X not in not in list let me have a look at this and I'll be right back okay so apparently I can't spell or read and I excellent typed random so that should be our anyways my apologies let's run this now and see if this works all right so there we go that's a pipe and that's another pipe and there's another pipe and if we want these pipes to spawn closer to each other then what we can simply do is just change this positions and rather than 700 to be 600 so if I do that because I believe I actually changed the width of my screen to be 600 I think I did then what will happen is these will spawn pretty much instantly once we pass and there we go we can see that that's what we get now if these are too like too close to you for you then obviously you can make that a bit wider but I find that this is a decent distance and right as you kind of pass one pipe it's disappearing as you go through the other one and it just it works well it gives you enough time to kind of get in between them so anyways that is how that works now we need to do a few other things here about our bird now the reason I haven't been moving our bird is because we're not gonna be using the arrow keys to move it right now what we're gonna do is we're gonna use an AI to move the bird and to actually play with it so that's why I haven't bothered implementing the mechanics of you know moving it up and down and actually testing it in that way so I guess the next thing we need to do is we need to check if the bird has hit the ground because once we start moving the bird if it hits the ground well we need to you know tell it it lost so for that what I'm going to do is just say if bird dot Y is I guess actually bird dot y plus bird image dot get underscore height if this is greater than the floor or the base where we did it which in this case is gonna be 730 then we're gonna say that we hit the floor so in this we need to do something I'm just gonna pass for right now but will you know we'll modify that in a second all right so now that we've done that we've actually pretty much coated the game of flappy bird now I know it doesn't quite seem like it there's a few more things you need to add like we'll draw the score up here but it's almost about time to actually start adding the AI to this because before we can start kind of working with collision and moving the birds and all this we need the AI to actually be operating the birds so anyways let's do one more thing here we're inside of our draw function which is here we start drawing the score so we'll add score in here and at the top of our program we'll create some fonts just for drawing these scores so I'm just gonna copy the ones that I have already so I'm gonna say for example stat underscore font and we'll just put this down one line is equal to pie game dot font dark sys font I believe it's sys underscore font not underscore sorry just font like that then what we're gonna say is Comic Sans and in here we're going to put 50 now we'll also do one more that's seventy for the score I believe or actually no I think 50 is fine for right now okay so we'll just leave 50 and now what we're gonna do is just render some font that tells us the score when we're playing so we actually can see that at the top so to do that is pretty straightforward I'm just gonna do it here I'm gonna say text equals stat font don't render and then in here we're gonna put our text that we want so this case gonna be score plus the string of score and then we're gonna do say one and we need to give it what's the last thing here anti-aliasing I forget what the last thing is that we need to put inside when we draw this I believe it might be the cut there I'll check in one second yes so it is the color so let's make this white so 255 255 255 and then let's draw this on the screens we're gonna say win double it text and then what we can do is do a little bit of fancy bleeding here so we're gonna say win underscore width minus 10 minus text dot get underscore width so this way no matter how big our score gets it actually show up on the screen and we'll keep moving it to the left to accommodate that now we'll draw it at 10 pixels and if I run this we should see the score font popping up Oh font is not initialized which means we need to add one more line of code to the beginning of our program which is pi game dot font dot an it it's kind of an annoying line to add but anyways put that up there and that should help fix this all right missing one required positional arguments score so that means that now we got to go down to our main loop and where we're calling draw window we need to throw score in here so let's run this and now we get score and let's see if it goes up when we pass the pipe and it does now obviously nothing's happening with this collision but that's we're gonna get into now as we start adding a few more things in talking about actually implementing the AIall right so now let's work in the main game loop and start getting all this to work together so we've successfully completed the bass we've completed the pipe we have the bird now it's just time to implement all of it so first I'm just going to change my draw window function a little bit so now I'm gonna add in an ability to draw pipes as well as the ability to draw the base so what I'm gonna do in here is just complete this already is I'm gonna draw all the pipes and the base so I'm gonna say for pipe in pipes and pipes are get is gonna come in as a list because we could have more than one pipe on a screen at once I'm simply gonna say not that pipe don't draw and we'll pass it a window so now for all of our pipes we will draw them next thing I'm gonna do is say bass drop and give it a window and that's as easy as it is to draw our stuff and that's why I really like creating these draw methods because they just make it super clean and we can do all of the drawing from the object itself all right so next we need to now add and create I guess a bass and some pipes so let's start by first of all just changing our bird position to be a little bit different so I'm gonna change it to actually be 23350 because that's where it should actually be located at least like that's what I figured out is kind of the best position and what I'm also gonna do is create a base now just gonna say base equals base and give this a height of 700 now this is because this is gonna be at the very bottom of our screen and that's where 700 is because I believe the height is 800 let me actually just look here to make sure I'm just looking at my other file by the way because I want to make sure I don't mess any of this up oh my bad actually we're not gonna make it 700 we're going to make it 7:30 it's a little bit lower okay so 730 that's where our base is now we're gonna make sure that we past pipes and base and I guess I need to still program pipes don't ever say say pipes equals a list and I'm just gonna throw one pipe in here right now and we'll start with it at a height of 700 okay so now that we have that this is gonna be weird but we can actually just draw this and see what this looks like to start so let's do control B here and you can see that we now have this base which isn't moving as well as this bird so if we want to fix this and allow it to move well let's do that so let's start by actually moving the base so let's say base don't move like this and now let's run this and see what happens and now you can see we have this moving base and it makes it look like our bird is actually kind of flying through the screen which i think is pretty interesting and that was pretty easy to do alright so now let's move all of our pipes and if we remember here if I go to pipes what do you call it here our pipe yes so it needs to move backwards because we give it a starting exhibition my apologies so anyway so let's now move all of our pipe so do this I'm gonna say four pipe in pipes because we might have more than one pipe in here on a say pipe don't move all right now let's see if we got a pipe moving on our screen all right give it a second and there we go we have some pipes they have a random height and they have started moving so now we need to do is figure out once that pipe kind of leaves the screen we need to generate another one and another one and another one so how do we do that well we're gonna do that inside of this four loop that we just created so what we essentially need to do is check the x position of our pipe and once it reaches certain point we need to create another pipe and then another pipe and then another one and then another one and so on so what I'm gonna do here is first we're actually going to check for collision with our pipes so I'm gonna say if bird are not very I'm saying if pipe dot collide bird then what we'll do is well we need to do something so in this case I'm actually just gonna pass for right now because I don't want to do anything with the bird quite yet but if we collide with the pipe well we need to you know end the game we need to actually do something now the next thing I'm gonna do is check the position of the pipe so I'm gonna say if pipe I go down here if pipe dot x+ pipe pipe underscore I guess whether top dog get underscore width is less than zero now what this essentially is checking is if our pipe is completely off the screen so by getting the x position of the pipe as well as the width of it if it's less than zero that means it's completely the screen then what we're gonna do is we're gonna remove that pipe now we can't quite just remove it from this for loop because we're looping through the pipes so what we need to do is create a list called Rama which is gonna stand for remove and we're gonna add that pipe to the list to remove so we're gonna say Ram dot append pipe and that's pretty straightforward all right now what the next thing we're to do is we're gonna say if not type dot pass and pipe dot X less than bird dot X row and you say type dot past equals true and we're gonna say add underscore pipe equals true now what this is gonna do for us is it's gonna check if we have passed the pipe so let's go back into our drawing thing here and I can't I have now I regret having stopped drawing the thing so anyways let's say that you know this is our pipe like this and let's say that this is our bird well as soon as our bird passes by this pipe what we need to do is generate a new pipe for it to start you know going through or whatever so that's what we're checking there as soon as we pass the pipe generate a new one anyways let's do that now so we say add pipe and then we continue to move these pipes now what I'm gonna do in here is get outside of this for loop and say if add underscore pipe then what we're gonna do is say score plus equals one which reminds me I need to create a score variable because once we pass a pipe well that means that we've gotten a point we need to keep track of that for our game then what we're gonna do is we're gonna create a new pipe I'm gonna add that to the screen so to do that is pretty straightforward we're gonna say pipes u dot append and in this case we're just gonna do pipe and we're gonna give it the same x position of 700 now after we do this we're going to remove those pipes that we had up here that we need to remove because they went off the screen I'm gonna say for our in in REM let us say pipes don't remove our and that should just get rid of our pipes for us alright so now that we have that we actually will see that our pipes will start generating properly on the screen so let's run this clicking the wrong key here what is my variable local add piped reference oh my bad we need to do ad underscore pipe equals false to start up here because you know if this doesn't happen we're not gonna define it so just make sure you add that at the top above remove let's run this and now we should see that our pipes start generating and as soon as we pass one pipe another pipe will generate hmm what is the air here X not in not in list let me have a look at this and I'll be right back okay so apparently I can't spell or read and I excellent typed random so that should be our anyways my apologies let's run this now and see if this works all right so there we go that's a pipe and that's another pipe and there's another pipe and if we want these pipes to spawn closer to each other then what we can simply do is just change this positions and rather than 700 to be 600 so if I do that because I believe I actually changed the width of my screen to be 600 I think I did then what will happen is these will spawn pretty much instantly once we pass and there we go we can see that that's what we get now if these are too like too close to you for you then obviously you can make that a bit wider but I find that this is a decent distance and right as you kind of pass one pipe it's disappearing as you go through the other one and it just it works well it gives you enough time to kind of get in between them so anyways that is how that works now we need to do a few other things here about our bird now the reason I haven't been moving our bird is because we're not gonna be using the arrow keys to move it right now what we're gonna do is we're gonna use an AI to move the bird and to actually play with it so that's why I haven't bothered implementing the mechanics of you know moving it up and down and actually testing it in that way so I guess the next thing we need to do is we need to check if the bird has hit the ground because once we start moving the bird if it hits the ground well we need to you know tell it it lost so for that what I'm going to do is just say if bird dot Y is I guess actually bird dot y plus bird image dot get underscore height if this is greater than the floor or the base where we did it which in this case is gonna be 730 then we're gonna say that we hit the floor so in this we need to do something I'm just gonna pass for right now but will you know we'll modify that in a second all right so now that we've done that we've actually pretty much coated the game of flappy bird now I know it doesn't quite seem like it there's a few more things you need to add like we'll draw the score up here but it's almost about time to actually start adding the AI to this because before we can start kind of working with collision and moving the birds and all this we need the AI to actually be operating the birds so anyways let's do one more thing here we're inside of our draw function which is here we start drawing the score so we'll add score in here and at the top of our program we'll create some fonts just for drawing these scores so I'm just gonna copy the ones that I have already so I'm gonna say for example stat underscore font and we'll just put this down one line is equal to pie game dot font dark sys font I believe it's sys underscore font not underscore sorry just font like that then what we're gonna say is Comic Sans and in here we're going to put 50 now we'll also do one more that's seventy for the score I believe or actually no I think 50 is fine for right now okay so we'll just leave 50 and now what we're gonna do is just render some font that tells us the score when we're playing so we actually can see that at the top so to do that is pretty straightforward I'm just gonna do it here I'm gonna say text equals stat font don't render and then in here we're gonna put our text that we want so this case gonna be score plus the string of score and then we're gonna do say one and we need to give it what's the last thing here anti-aliasing I forget what the last thing is that we need to put inside when we draw this I believe it might be the cut there I'll check in one second yes so it is the color so let's make this white so 255 255 255 and then let's draw this on the screens we're gonna say win double it text and then what we can do is do a little bit of fancy bleeding here so we're gonna say win underscore width minus 10 minus text dot get underscore width so this way no matter how big our score gets it actually show up on the screen and we'll keep moving it to the left to accommodate that now we'll draw it at 10 pixels and if I run this we should see the score font popping up Oh font is not initialized which means we need to add one more line of code to the beginning of our program which is pi game dot font dot an it it's kind of an annoying line to add but anyways put that up there and that should help fix this all right missing one required positional arguments score so that means that now we got to go down to our main loop and where we're calling draw window we need to throw score in here so let's run this and now we get score and let's see if it goes up when we pass the pipe and it does now obviously nothing's happening with this collision but that's we're gonna get into now as we start adding a few more things in talking about actually implementing the AI\n"