Students who learned Python for the first time might notice the difference between Scratch and Python. They could write with Python’s built-in functions and deal with the interaction with end user only through the print() and input() functions. Sometimes, it is a bit boring since no any graphical interface is included.
Some might ask if we could learn Python by designing games, considering that Python has Pygame library. So is it a good choice to start learning Python through Pygame?
In this post, I would like to introduce a simple game coded with Python’s Pygame library and we could compare what is the difference between Scratch and Pygame development.
The game demo is shown below. If you would like to read the source code, a downloadable hyperlink is attached at the end of the post.
Please note that before running this game, you need to install Python and Pygame on your computer. Here I will not explain the installation steps. The Python version I am using is 3.9.0 and Pygame version is 2.0.1, but you could use different Python and PyGame versions.
Starting Part of the Program
At the beginning of the program, we need to import pygame, random and math library. In the second line, we use “from pygame.locals import *”. This format allows us to skip the module name pygame.locals and simply use the attributes and methods within that module directly.
The program then specifies constants WINDOWWIDTH, WINDOWHEIGHT. In Python, we usually define constants in all-capital format to differentiate them from common variables.
For the next step, the program defines two short functions. One function “check_distance”, as its name specifies, is used to return the distance value between two points in the window. The other function “image_center” is used to return the center point position of an image.
The “image_center” function have two parameters. The first one represents the reference to the image, while the second one represents the position of the image. In Python, position of a sprite refers to that of its top-left corner. In order to get the center position of the image, we calculate based on the rectangle’s size and the position value of top-left corner.
Here, you might have noticed the difference between Scratch game and Pygame. In Scratch, distance between two sprites has corresponding programming block “distance to”. The image center is the “x position” and “y position” of the sprite. What we need to do is just to use those blocks directly. While in Pygame, you need to write your own functions to implement those stuff.
Unlike Scratch which offers parallel code segments, Pygame requires a function to act as the single main entry of the program. You could name it any meaningful names. For this game, I just name it “Main”.
At the beginning of the function, it uses “pygame.init()” to initialize the game environment, which should be called first in order for many Pygame functions to work.
The next step of the program is to use pygame.display.set_mode to set display surface for the window. The previous constants WINDOWWIDTH and WINDOWHEIGHT forms a tuple to tell the set_mode() function how wide and how high to make the window in pixels. Display surface is where all the images will show. After that, it sets capital text, font type and font size. Those items are pretty routine, so you could apply the similar code to other projects.
The program now needs to load all the relevant images by using pygame.image.load() function. Please ensure that the images are put in the current directory or within the folder or sub-folder of current directory. Except background image, all the sprite images should use PNG format so you will not see the ugly image background.
Here you could observe another clear difference between Scratch and Pygame programming. In Scratch, images could be stored and edited in Costume Editor, while in Pygame, you need to load them all by yourselves. Image editing should be done through other tools.
For the butterfly sprite, we have 8 pictures to capture its different postures. If it is in Scratch, what we need to do is to store all of them as 8 costumes. In Python, all of the 8 images should be loaded and stored in a list, which is named “butterfly_images”. pygame.transform.rotozoom function could used to rotate and scale the loaded image.
In the above code segment, there is a variable called FPS, set to 30. It represent frame rate per second. The frame rate or refresh rate is the number of pictures that the program draws per second. A pygame.time.Clock object can help us make sure our program runs at a certain maximum FPS. This Clock object will ensure that our game programs don’t run too fast by putting in small pauses on each iteration of the game loop. If we do not have these pauses, our game program would run as fast as the computer could run it.
It is easy to broadcast background music for your game. Just use pygame.mixer.sound to load a voice file and call play method. The -1 argument makes the background music forever loop when it reaches the end of the sound file. The 0.0 means to start playing the sound file from the beginning.
The next step is to enter into a forever loop. This game loop (also called a main loop) is a loop where the code could handle keyboard and mouse events, update all the relevant variables/lists/images or game status, and draw the images to the computer screen.
The program first sets butterfly_x and butterfly_y variables, which represent the upcoming position of the butterfly sprite. Please note that both butterfly_x and butterfly_y use random value, so each time, the flying trace could be different.
The program will iterate each event item stored in the event list (returned by pygame.event.get() function). Any time the user does one of several actions, such as pressing a keyboard key or moving the mouse on the program’s window, a pygame.event.Event object is created by the Pygame library to record this. Event objects have attributes named type which tells us what kind of event the object represents. Please note those event type constants such as QUIT, MOUSEMOTION, MOUSEBUTTONUP are located in pygame.locals modules. Since we use the form “pygame.locals import *” format at the beginning of the file, we only have to type QUIT instead of pygame.locals.QUIT.
The program uses several “display_surface.blit” functions to “paste” the images into display_surface object. display_surface object only exists in the computer’s memory and “paste” image onto it is much faster than “drawing” on the computer screen. Only at the last step of the main loop, the program calls pygame.display.update() function to draw the “display_surface” object to the screen.
The last step following “pygame.display.update()” is to call “fpsClock.tick(FPS)”, which calculates how long it has passed since the last iteration. If the time interval is too short, the program will pause here to ensure that the game runs at the speed of FPS no matter how fast of a computer it runs on.
That is all the code for this program. You could download the source file here.
You might have noticed that Pygame style is totally different from Scratch, and much more complicated. In the next post, I would like to introduced a simplified library Pgzero and made a comparison to Pygame. Stay tuned!
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.