Lecture 9 | How to draw the game background?

In the previous article, we described various basic knowledge, then sorted out the development process, and took you to create a form. Now all we have to do is add things to this form.

The difficulty will gradually increase as the progress progresses. At this stage, we only cover some basic knowledge, and we only need to focus most of our attention on the game content we want to do, and do not need to pay attention to too much underlying logic code.

There is a sequence for doing things, and the same goes for game development. Why you need to learn to draw the game background first instead of anything else is very simple, because only by drawing the game background first can you perform subsequent operations such as game image occlusion, graphic image display, etc.

Regardless of whether you have played games such as “Super Mario”, “Contra”, or “Thunderbolt”, you must be familiar with their graphics. Just like the masturbation game we are about to start, the background of this type of 2D game is either left and right scrolls or up and down scrolls. The so-called left and right scroll means that the game screen is horizontal and moves left and right, while the up and down scroll means that the game screen is vertical and moves up and down.

Classic airplane games like “Thunderbolt” are top-down scrollers. One characteristic of the top-down scrolling airplane game is that it is in the air, looking down at the ground from a perspective above the airplane. Because it is a bird’s eye view, we can easily see the overall map of the game, including enemies on the ground, enemies in the air, etc., and the sense of hierarchy will be very strong.

Therefore, it can be determined that the masturbation game we are going to do is also a top-down scrolling game. In this way, we can start adding the required pictures.

We are going to use Pygame, first read an image, make the image become the game background and load it. At this stage, it doesn’t matter where we get our pictures, because in a complete game development team, there is a professional art team responsible for drawing, but we don’t have one now, so I will post a picture myself instead of the official one. Game background. So now you just need to know how the background is attached.

As mentioned in the previous article, we need to load the Pygame module first and define a variable background. We assign a picture file named lake,jpg to the backgroud variable.

import pygame
background = 'lake.jpg'

Then, we first initialize all components of Pygame. Next, we call the set_mode function in the display class to initialize the screen.

pygame.init()
screen = pygame.display.set_mode((640, 480), 0, 32)
pygame.display.set_caption("pygame game")

There are three parameters here. The first parameter is resolution. For example, the resolution I am writing here is 640×480; the second parameter is flag, the flag parameter. I put it in the table below; the third parameter is 32, 32 represents the color depth, here it means 32 bits.

After setting the form mode, the following piece of code is to set the header text of the form. What is shown here is pygame game.

Next, we need to load the image for the background.

bg = pygame.image.load(background).convert()

As mentioned in the previous article, the meaning of this sentence is to load the background image. But the pygame.image.load function returns a surface, and the .convert function comes from the surface object. You can refer to the code below to understand.

surface_temp = pygame.image.load(background)
bg = surface_temp.convert()

Secondly, the bg variable is also a surface, and the convert function is used to change the pixel format of a picture. convert has four overloaded functions with the same name. If convert does not have any parameters as shown in our code, it means directly returning a surface object.

Okay, now that we have set up the surface of the background bg, we follow the above article and start writing a large loop, and inside the loop we detect whether the mouse event is an exit operation. This is the most basic detection.

while True:
    for event in pygame.event.get():
        if event.type == QUIT:
            pygame.quit()

As in the previous article, we take out the event list from event, and then compare the types of each event. If a QUIT event is found (after clicking the X close button with the mouse), we will exit the game directly. After completing this step, you can start using the blit function to draw the screen.

screen.blit(bg, (0,0))

What this sentence means is, use blit to draw the background image on the screen object at the coordinate position of bg with the game screen’s x, y axis as (0,0). Then we need to update the screen and add the following line of code.

pygame.display.update()

upadate This function is an optimized version of the pygame.display.flip function. Because pygame, display.flip updates the entire screen, so if a lot of resources are loaded, the efficiency is not very high. If update passes a rectangular value parameter, it will only update the content of the rectangle, so the efficiency will be higher. , but if no parameters are passed, the entire screen will be updated by default, but this function cannot be used in the OpenGL mode when set_mode is used.

Okay, we have basically done what we should do, now let’s run it and see the effect.

Okay, the background is pasted. Now the question comes, what should I do if I want to make the background move? If during blit, can the position of the background image be moved by changing the coordinates? If you think about it again, what should you do to make the background move?

Yes, we only need to write a loop to move the background.

Let’s modify the code at the beginning of the big loop.

y_move = 0
while True:
    for event in pygame.event.get():
        if event.type == QUIT:
            pygame.quit()
    screen.blit(bg, (0,y_move))
    y_move-=1

Before the big loop starts, we define a variable that moves the y value in this code. Every time we loop, blit draws the screen once, and the y value will be subtracted by 1, so every time we see the picture, It will keep moving up, let’s take a look at the effect.

Did you find the problem? During the movement, the pattern below was not refreshed and stuck directly to the screen. Doesn’t it look disgusting?

What should we do to achieve normal results? In other words, please think about it, what should we do so that we can make this troublesome image normal when moving?

Let’s first review what steps we did in the loop:

Detect exit events;

Draw the bg object on the screen, the coordinates are initially (0, y);

Every time the aircraft moves one space, the coordinate y decreases by 1;

Update screen.

It seems that there is no problem, let me sort it out for you.

First, when we initialize, the screen is black without any images. Then we enter the big loop and draw the bg object to the screen. Do you think our eyes see the drawn image at this time?

If you say yes, you are totally wrong, becausethis blit action is only drawing, not displaying. Remember this distinction: Drawing is not the same as showing.

Then you may have to ask, since it is drawn, why is it not displayed? When will it be displayed? The answer is that it will only be displayed when the screen is updated once. This is the role of “update”. Just like a movie moves frame by frame, if there is no update to the next frame, the movie will always freeze at a certain second.

So the problem gradually came to light. Let’s reorganize the process:

Detect exit events;

Draw the bg object on the screen, the coordinates are initially (0, y) (note that this is drawing, not display);

Every time the aircraft moves one space, the coordinate y decreases by 1;

Update the screen and present the bg object drawn in the second step on the screen. Strictly speaking, all drawing operations before the update function should be updated once and presented on the screen).

Okay, the problem is very clear. The update function only updates the screen once and does not fill in the color or “erase” the background. That is, when we move the y value, the entire screen keeps updating. , however there is no erasure. So how should we clean up the moved screen?

We fill in the following code after the update code.

screen.fill([0,0,0])

The fill operation has three parameters, the first parameter is fill color; the second parameter is fill a certain area ((If the second parameter is not filled in, will fill the entire screen); the third parameter is a special parameter of the blit operation, we can ignore it for the time being.

Therefore, we fill the entire screen with black in the code, so that our screen operation becomes like this:

Detect exit events;

Draw the bg object on the screen, the coordinates are initially (0, y);

Decrease the coordinate’s y by 1;

update screen;

Fill the screen area with black.

Let’s run it again to see the effect.

It looks normal now, the screen keeps moving up, and there is no longer a tail-like pattern.

Summary

When we write 2D games, we need to pay attention to one thing:

We have to imagine that every frame of the game is like every frame of the movie. What is done in each frame, if it is not done in the next frame, the screen content will never be updated.

Therefore, the function of update is to update all actions before calling update. These actions can include drawing image operations, music playback, and operations for each frame of animation, etc. As long as you update once, the screen will move forward once.