In the previous post, I introduced a simple game: Catch Butterfly. It uses Python Pygame framework to create a 2D interactive game. You might have noticed that using Pygame seems not an easy task. However, if you get familiar with Pygame structure and functions, even more complicated game is not a problem.
In this post, I would like to introduce another game, which is converted from a Scratch game called Forest Maze. You could find and play the Scratch game at this address: https://scratch.mit.edu/projects/437052483/
The final effect of the game is shown in the following video clip:
As usual, we will explain the code segment by segment. Let’s start now.
At the beginning of the Python file, the program imports all the libraries to be used, including Pygame, random, math and time modules. It sets several constants to specify window width, height, size and color value. All of those settings are similar to those in Catch Butterfly project.
The function “image_pos” has two arguments. The first one refers to the image surface object, and the second one specifies the center position of the same image. This function is used to get the image surface’s position (the top-left corner’s position of the bounding rectangle). We will use this function to get Obstacle sprite’s position dynamically later in the code.
After simple initialization at the beginning of the file, comes the main function. It first calls “pygame.init()” to initialize the pygame running environment. As we introduced in Catch Butterfly project, this step is compulsory in all the pygame projects.
The program then goes forward to set window caption, font size and font type. It loads background image and scales it to the same size of window. The method “background_image.convert()” is used to convert the pixel format of the image surface and ensure its has the same pixel format as the display Surface. This is always the fastest format for blitting. Therefore, it is strongly recommended to convert all Surfaces object before they are blitted.
After that, the program copies background image surface and then creates a mask surface. You might feel confused when reading this code. This step is closely related to purpose of the project.
In this game, when any knight touches the light green color in the background image, the knight will go back to starting place. However, in Pygame, there is not such a function called “touch (color)” just like in Scratch. We need to create a mask surface which could “mark” only the place of specified light green color on the background image. For those places not occupied by light green color, the mask surface will mark them as transparent.
This functionality is done by calling “pygame.mask.from_surface” and “background_mask.invert()” methods. The former one creates a mask surface on which the light green color is set as transparent. The latter one flips the mask surface, so only the light green color is marked and other places are marked as transparent.
The next step in main() function is to load all the 10 letter images. Those letter images represent the letters from 0 to 9. They are stored in a list called letter_images.
The program then set FPS and Pygame block. This is to ensure the main loop could run at a stable speed. I have introduced this functionality in Catch Butterfly project, so just explain it briefly here.
For the two knight sprites, the program also loads their images and uses “pygame.transform.rotozoom” function to scale them to a certain level. Please note that functions “scale” and “rotozoom” are similar, but they use different arguments. “scale” function is to zoom the image into the size of a specified rectangle, while “rotozoom” is to rotate and zoom an image by specifying its rotation angle and zoom factor.
The program continues to load castle image, obstacle and win banner images and rotozoom them.
It specifies the knight’s x and y initial positions and stores them in variables Knight_1_x, knight_1_y, knight_2_x and knight_2_y.
Till now, the program has initialized all the variables and loaded the image surfaces. It uses “pygame.key.set_repeat” method to specify the keyboard repeat behavior. For this game, when arrow keys (or ASWD) are pressed, the knight sprite will move in the specified direction. Without using “pygame.key.set_repeat” method, whenever a key is pressed, there is only one key pressing event getting invoked, no matter how long the user presses a key.
If we would like to make the knight move continuously when key is pressed, we need to use “pygame.key.set_repeat” method so that keys that are held down will generate multiple
pygame.KEYDOWN events. The first argument
delay is the number of milliseconds before the first repeated
pygame.KEYDOWN event could be sent. The second argument “interval” specifies the waiting interval before another
pygame.KEYDOWN event could be sent.
The event loop is pretty standard. it checks the event type first. If event type is QUIT, meaning to click X button on the game window, the pygame will stop running. If event type is KEYDOWN, the program will collect all the key pressing events into a dictionary called “keys”. Each key on the keyboard is represented by a constant key. For example, up arrow key is represented by K_UP. Through checking the value of dictionary item, The program knows when and how to change the value of knight_1_x, knight_1_y or knight_2_x, knight_2_y.
That is the first part of the Pygame Forest Maze. In the next post, I will continue explaining the second part of the game. Keep tuned! and enjoy the coding and have fun!
Note: All the analysis articles are copyright products of http://www.thecodingfun.com. Anyone re-posting them should credit author and original source. Anyone using them for commercial purposes or translating them into other languages should notify TheCodingFun and get confirmation first. All Rights Reserved.