how to make flappy bird in python

Sign up or log in Sign up using Google Sign up using Email and Password

Required, but never shown

4 Answers 4 Sorted by:

  • Because you have docstrings for your functions and classes, your code is superior to 2095% of the code that is submitted to Code Review.
  • The PipePair class, the motion, drawing, and destruction logic in the main, the scoring logic in the main, and the factory function random_pipe_pair are the various components that make up the behavior of the pipes. If you gathered all of the pipe logic into methods on the PipePair class, the code would be simpler to read and update.
  • The behavior of the bird is similarly dispersed across multiple locations: (i) the local variables bird_y and steps_to_jump in main; (ii) the flapping animation logic; (iii) the “calculate position of jumping bird” logic; and (iv) the get_frame_jump_height function. If you gathered all the bird logic into methods on a Bird class, the code would be easier to understand.
  • The behavior of the bird doesn’t seem to be well described by the term “jumping.”
  • Name is_bird_collision make not sense English.
  • You are essentially checking for the intersection of rectangular hit boxes in the collision logic. Pygame offers a Rect class with a number of collide methods to help you write clearer code and facilitate debugging tasks like drawing hit boxes.
  • When it comes to removing a pipe, the list method of storing the pipes is ineffective. remove takes time proportional to the length of the list. You ought to utilize a collection, or a set, as you are aware that pipes are formed on the left and destroyed on the right. deque.
  • After storing the collision results in a list, you test to see if True is an element of the list to check for collisions. Instead, you should use the built-in function any: if any(p. collides_with(bird) for p in pipes): (This also has the benefit of short-circuiting, which means it stops testing the remaining pipes as soon as a collision is detected rather than continuing. ).
  • Frames are used to measure time; pipes, for instance, move leftward at a specific number of pixels per frame. As a result, you are unable to adjust the framerate without also adjusting a number of other parameters. Time can be measured more broadly in seconds, which allows for framerate variation. (In simpler games like these, you can get away with measuring in frames, but in more complex games, you’ll need to be able to adjust the framerate, so it’s important to practice the required methods.) ).
  • You broke the game in commit 583c3e49 by (i) deleting the random_pipe_pair function without altering the caller, and (ii) altering the surface local variable to an attribute self. surface in some places but not others. Although mistakes are occasionally made in commits, the fact that there are four commits after this one indicates that you may not have been testing your code before committing it. This is a bad habit to get into!.

I can still pick apart this code a little bit, but it’s pretty nice.

You could use the cool . < . < . operator for this:

like this:

Adding a few line breaks might make random_pipe_pair a little easier to read.

Moot point, but I’ll leave it in any case; see my conclusion below

You dont need the parentheses here:

and here:

and here the outer parens:

and here:

BUT. As you noted, you primarily use parenthesis to permit lengthy line breaks (likely in accordance with PEP8) without the unsightly That makes perfect sense, so go ahead and keep them! (In fact, I had no idea this was even possible, so thanks for the lesson, teach!)

  • I am not comfortable with pause handling. First, the busy-waiting loop. Second, the game is paused but continues to serve events even though it doesn’t render anything. g. pipes are added.
  • random_pipe_pair really wants to be a PipePair constructor. Similarly, s[pipe_body] and s[pipe_end] should be static members of PipePair.

This is neat 🙂

In my opinion, unless you are monitoring the corrected values, display update() is no better than display. flip(), though I suppose it would be simpler to read for a student.

The reason for my curiosity is that, although I understand that in an event loop scenario the actual order of processes can be a little loose, particularly if you’re working at a high frame rate, and that the code is presented so that the “exit or don” code appears at the end of the loop, I think that all state checking should take place prior to the view updating. I don’t know the age or experience of the students you are working with, so that’s probably small potatoes.

I must admit that the paused handling is a little strange, if only because it raises an interesting point about the use of states to regulate the (very brief) script’s flow. Would prefer to see “if paused: continue” replaced with something more along the lines of “if not paused: do_stuff().”

The PyGame API features you’ve decided to work with are also kind of interesting; personally, I find it quite weird to teach an Intro To Games class without using sprites. The Pygame sprite. Although having a sprite object around is quite useful, the code seems to introduce a number of different concepts, so perhaps there’s no need to add yet another concept to the mix.

Thanks for contributing an answer to Code Review Stack Exchange!

  • Please be sure to answer the question. Provide details and share your research!.
  • Asking for help, clarification, or responding to other answers.
  • expressing opinions and supporting them with references or firsthand knowledge

Use MathJax to format equations. MathJax reference.

To learn more, see our tips on writing great answers. Draft saved Draft discarded.

1 Answer 1 Sorted by:

The game is too hard for me. As for the code, I appreciate the comments. I want to emphasize that everything should be put into the appropriate classes, functions, and files.

Separate all the constants/settings/parameters to another file. In this manner, everything is in one location in case you need to change the parameters or add difficulty levels later on.

constants.py

As for the colors, youve coded them in instance declarations. I advise using distinct variables to choose the colors of the objects and an Enum to define all the colors you’ll need. In this manner, you can experiment with colors and objects on your own in the future. In constants. py or another file.

Youve defined classes for players, which is good. Consider using dataclasses. They let you skip all the boilerplate init code and add useful methods for printing and equality checks. Your objects also share a few attributes such as position, size and color. These are common to any game object and if you were to add any new type of game object they woud have it too. Maybe its a good idea to define an abstract UI object class:

In your main file, your code logic is disorganized. I advise you to divide the logic for every class into its own methods. Spawning players or obstacles should be class methods. A Player instance method should check to see if the player is out of bounds. Using the Player or Obstacle instance method to determine whether the player has encountered an obstacle Also you update object positions for players and obstacles separately. I would group the logic together into the abstract class.

game_objects.py

Its recommended to use a __main__ == "__name__" check in your python scripts mainly to prevent accidental execution of the script. I created a Game Class to organise the code but you could just as easily achieve the same with functions only.

In your code, you render the player, the background, and the obstacles independently at various points in time and space. If you were to decide to render your game differently, you would need to make changes to the code in each of these locations. Put code that does the same or similar things together.

I organized everything to create a basic-looking game loop.

  • You can use A B C in place of (B > A) and (B < C).
  • Avoid getting too caught up in if-else statements; there are typically simpler ways to
  • There are too many flags! The running and lost flags are unnecessary. You can always return or quit().
  • In general avoid import *
  • I also modified how you handle new obstacles so that it now handles them in terms of space instead of time. It makes handling pauses easier and lets you modify the obstacle’s speed without also changing the interval.

All in all really good code for a first project. To help players learn various concepts, you could incorporate score keeping, difficulty levels, and possibly save and reload games.

Final script: main.py

Thanks for contributing an answer to Code Review Stack Exchange!

  • Please be sure to answer the question. Provide details and share your research!.
  • Asking for help, clarification, or responding to other answers.
  • expressing opinions and supporting them with references or firsthand knowledge

Use MathJax to format equations. MathJax reference.

To learn more, see our tips on writing great answers. Draft saved Draft discarded.

FAQ

What code does Flappy Bird use?

Flappy Bird is so ridiculously simple that you could implement in any language capable of displaying graphics. So that includes Python, C#, Java and on an on all the way up to C++ and down to assembly.