Make flappy bird with Python Play
Demo and Code 👨💻
If you haven't played flappy bird before, try it out on flappybird.io!
🎓 So, how exactly does flappy bird work?
There are two objects which matter in the game - the bird and the pipes. In the demo above, the bird is the yellow circle, while the pipes are the blue rectangles.
The bird remains in the same
x position for the entire game, but can move up when the player presses a key, and continues to fall due to gravity.
The pipes are two rectangles with a gap between them - the bird needs to get through the pipes without touching them.
🛣️ Get started
Let's begin by forking repl.it/@jajoosam/play-start - Which is just a python environment with the
play dependency installed.
Let's start off creating flappy bird by creating a yellow circle to represent the bird:
bird = play.new_circle( color='yellow', x=play.screen.left + 100, y=play.screen.top - 40, radius=30, )
Running that code will result in a
yellow circle, close to the
left corner of the screen with a radius of
🌎 Physics is... easy!
We want our bird to be affected by gravity, and bounce back up when it falls to the bottom of the screen. So let's create a whole physics engine to do that!
lol jk, just add this one line to your code:
yep, that's it. really!
If you run your code now, you'd see a yellow circle falling down, and bouncing back up! We want to be able to make our bird flap though - make it jump when we want to.
We can use
play.repeat_forever to run a function every frame of our game - and in this case, if the
up arrow key is pressed, our
y coordinate increases by
@play.repeat_forever def do(): if play.key_is_pressed('up'): bird.y += 7.5
🚬 Let's roll the pipes
We're going to create pipes in sets of two, for blocking our birds - and store all of them in a list.
Near the top of your code, add a new line to create this empty list.
boxes = 
We want the two pipes we generate each time to have different height, and a gap in the middle. We also want to generate the next pair of pipes after a random duration, to make the game more unpredictable.
It'll be very useful for us to use python play's
random_number function here.
# Returns a integer between 300 and 500 play.random_number(lowest=300, highest=500) # Returns a float between 1.0 and 3.0 play.random_number(1.0, 4.0)
Add this entire block of code, just before
@play.repeat_forever async def block(): # height of the top block top = play.random_number(lowest=300, highest=500) # height of the bottom block bottom = play.random_number(lowest=300, highest=500) # creating the top box of width 50, emerging from behind the current screen boxes.append(play.new_box(color="blue", y=play.screen.top, x=play.screen.right+50, width=50, height=top)) # creating the bottom box of width 50, emerging from behind the current screen boxes.append(play.new_box(color="blue", y=play.screen.bottom, x=play.screen.right+50, width=50, height=bottom)) # creating the next box after a random duration between 1 and 4 seconds await play.timer(seconds=play.random_number(1.0, 4.0))
This code is inside an
async function - which is why we can use the
await keyword to delay each call by a particular duration, with
play.timer - this lets us create new boxes at an interval!
play.new_box - we create a new pipe and then append it to the
boxes list too. Try playing around with the parameters we supply to this function. they should be understandable!
But if you run the code now, you'll notice that everything is the same as before 😕
🖥️ Bring the pipes to the screen
Since all our pipes are in the same
boxes list, we can move all of them pretty easily, by looping over the list.
Adding this block to your code, under
def do(): makes the boxes move through the screen!
for box in boxes: # make the box move to the left box.x -= 1
This is what you should see when you hit run!
🤔 But... when do you lose?!
I'm really going to sell you on python play by explaining how we can detect collisions.
bird.is_touching(box) - that's it. No cap 🧢
In our same loop, where we're moving the pipes to the left, just add this condition block:
if bird.is_touching(box): box.color = "red"
If the bird ever touches the pipe, it's color shall be red!
Also add this block in the loop:
if(box.x < (play.screen.left-50)): boxes.remove(box) box.remove()
We're just preventing memory leaks with this - if our pipe is out of the screen, let's just remove it!
🔮 Things to hack on
- Use pixel art of a bird instead of the yellow circle 👨🎨
- Restart the game when the bird touches the pipe ☠️
- Add power-ups to the game 💪
- Add a live score to the screen 💯
Be sure to put down any questions or improvements down in the comments 💬
And here's all the code for you to go over again - I've annotated it for you too 😄