If you are not familiar with Object-Oriented programming in Python, familiarize yourself now.
Here is a class definition for a SceneBase:
When you override this class, you have 3 method implementations to fill in.
- ProcessInput - This method will receive all the events that happened since the last frame.
- Update - Put your game logic in here for the scene.
- Render - Put your render code here. It will receive the main screen Surface as input.
Of course, this class needs the appropriate harness to work. Here is an example program that does something simple: It launches the PyGame pipeline with a scene that is a blank red background. When you press the ENTER key, it changes to blue. This code may seem like overkill, but it does lots of other subtle things as well while at the same time keeps the complexity of your game logic contained into a snazzy OO model. Once you start adding more complexity to your game, this model will save you lots of headaches. Additional benefits are listed below.
Other awesome things you can easily do with this:
- You can change the screen mode with a hotkey. With the event filtering, you can add another clause to check for something like 'f' or F11 and then re-initialize the display to fullscreen or something. (if you pass pygame.FULLSCREEN in as a 2nd argument to pygame.display.set_mode, it will create a fullscreen window)
- Another huge advantage is you can create your own input model. Instead of simply filtering out pygame events, you can map the pygame events to your own event class. Instead of checking for pygame.K_SPACE to see if Hero Dude should fire his lazor, you can create a custom event where your check looks something more like myevent.type == 'FIRE_LAZOR'. The beauty of this is you can write an input configuration menu where you can map keys to actions or offer presets for various keyboard types (such as Dvorak users who get angry at programmers who use w/a/s/d keys for movement). Putting this logic in one centralized location keeps you from having to worry about all this each time you need to check the keys (just be sure to modify get_pressed accordingly if you do this).
- Ditto ^ for JoyStick/Gamepad functionality.
- Currently, the user cannot resize the window. In a traditional code layout, you'd have to rewrite all your render code to take into consideration the scale of the resized window. However, you can modify the above code to create an intermediate screen Surface object that you pass in to the scenes' Render method. This intermediate screen will be the size of the logical width and height of the game (in this case, 400 x 300). Then, for each frame, you can use PyGame's scale transforms to adjust the logical screen to the size of the real window. This way, your code can pretend that the size of the window is always 400 x 300, but the actual size of the window is unconstrained.
Remember, clean code is happy code!