Lecture 12 | How to set the deformation, enlargement and reduction of the sprite?

The previous section explained the occlusion problem of images. In this section I want to talk to you about the deformation, enlargement and reduction of elves. If you have never done game development before, you will definitely ask, what are elves?

What are elves?

First, let’s explain what an elf is. Elves are certainly not elves in the woods in our traditional sense. Elf is a term used in game development, and its English name is Sprite.

It is mostly used for characters and movable items in games, and can also be used to display the mouse pointer and entered text. If the size of the movable object on the screen is larger than one sprite, it can be scaled or spliced from several sprites.

From a macro concept, an elf is a picture. For example, the airplane pictures and background pictures we talked about before can be considered as elves or derived from elves. It’s just a series of images that can change. These pictures can be transformed, enlarged, reduced, or a series of animation frames, etc.

From aprogramming perspective, an elf is a manager. In a sprite manager, there may be a series of methods to operate sprites, such as addition and deletion operations, image deformation, enlargement, and reduction operations, and series frame display operations.

Since the elves are pictures, in “Jerking Off”, the airplane will deform, enlarge and shrink as the picture changes and the operation is different. I will now talk about the implementation of these operations, which functions are needed, and what techniques are behind it.

What functions are needed to set transformation, enlargement and reduction?

The bottom layer in Pygame uses the SDL development library, which we have already mentioned in the previous content. Therefore, these operations such as deformation, zooming in and out, etc., have corresponding SDL libraries.

What we are going to use is the previous airplane picture. In order to let you see it more clearly, I deleted the background and only showed the contents of the airplane.

Flip function flip

The first thing we need to use is the function flip. As the name suggests, this function allows you to flip the image, you can flip it horizontally or vertically. So it has two parameters, one is passed in x, one is passed in y, and both need to be passed in Boolean values. If the incoming x value is true, then perform a horizontal mirror flip. If the y value is true, then perform a vertical mirror flip. If both are true, both sides will be flipped. This function returns a surface.

pln_t = pygame.transform.flip(pln, 1, 1)
screen.blit(pln_t, (40, 350))

The result we see is this:

Originally the nose of the plane was pointed upward, but now it flips horizontally and vertically.

Scale function scale

Let’s take a look at thescaling function scale. The parameters of scale are as follows:

scale(Surface, (width, height), DestSurface =None)

The first parameter is the drawing object, the second parameter is the zoom size, and the third parameter is generally less used and refers to the target object.

pln_t = pygame.transform.scale(pln, (220,220))
screen.blit(pln_t, (20, 150))

In the code, we enlarge the pln object to 220×220 (the original size of the aircraft is 195×62), and then take a look at the effect.

The plane got bigger. Let’s try modifying the code again.

pln_t = pygame.transform.scale(pln, (20,20)) 

The plane becomes smaller. Therefore, the function of the scale function is: As long as the width and height values that you pass in are greater than the original length and width of the elf, it will become larger, otherwise it will become smaller.

Similarly, we also have a function scale2x. You only need to fill in the drawing object, and the function will help you double the expansion. You do not need to calculate the original length and width values and multiply them by 2.

Rotation function rotate

Let’s take a look at the rotate rotation function. It provides a parameter angle, which is the angle you need to rotate, either positive or negative.

Let’s take a look at the code.

pln_t = pygame.transform.rotate(pln, 20)

The effect we see is something like this.

This rotates the aircraft 20 degrees to the left. Similarly, there is also the integrated function rotozoom. This function provides rotation and expansion functions.

If the code is written like this:

pln_t = pygame.transform.rotozoom(pln, 20, 2)

The effect we can see is this:

Cut function chop

Next is the function chop, which provides the function of image cutting. We need to pass in a drawing object and a rect rectangle, so that the contents of the input rectangle can be cut out.

pln_t = pygame.transform.chop(pln, [20,150,25,155])
    screen.blit(pln_t, (20, 150))

Let’s take a look at the content of the code. When we blit, we place pln_t at the position of (20,150), so when we chop, we will cut a rectangle like [20,150,25,155].

Then let’s take a look at the effect.

With so many functions, is it difficult to remember them? Let me summarize this part:

All functions for enlarging, reducing or transforming sprites are in the pygame.transform module. It provides a series of transformation operations for 2D elves, including rotation angle, zooming in, mirroring, stroking, cutting and other functions, allowing you to easily process 2D elves in the game as you wish.

Sprite in Pygame

Let’s take a look at Pygame itself. Pygame itself provides the Sprite module. The Sprite module provides the Sprite class. In fact, the most convenient function of Pygame’s sprite class is to animate certain sequence frame pictures and save them in the Sprite inside the group. In Pygame, Sprite is a lightweight module. What we need to do is to inherit this module and overload certain methods.

Class explode

We now have a picture, the effect is to hit a certain point and start to explode the pattern.

This picture has three frames in total and is a standard sprite animation. So what we need to do is to import this picture into the elf class first. Let’s make a class explode:

class explode(pygame.sprite.Sprite): 

This class inherits from the Sprite class, and then we define an initialization function and first call the initialization of the upper base class.

 def __init__(self, target, frame, single_w, single_h, pos=(0,0)):
        pygame.sprite.Sprite.__init__(self)

In this class, we see the definition of the function. The first parameter self will not be explained too much; target is the target image we need to load; < strong>frame means we need to tell this class how many frames our animation has; single_w, single_h represent the length and width of each frame of our animation. Here, each frame of our animation is 262×262. pos tells the screen where to place this animation on the screen.

Next, this is the initialization code I wrote:

def __init__(self, target, frame, single_w, single_h, pos=(0,0)):

        pygame.sprite.Sprite.__init__(self)

        self.image = pygame.image.load(target).convert_alpha()

        self.main_image = self.image

        self.frame = frame

        self.rect = self.image.get_rect()

        self.count = 0

        self.single_w, self.single_h = single_w, single_h

        self.rect.topleft = pos 

You should be able to understand most of the code, but there are a few points that require special explanation.

The first is main_image. This is to save the main image picture. When we switch frames later, we need to cut the next few frames in main_image and present them on the screen, so that the animation effect will appear in the visual effects. count is the current count for each frame. Here we have a total of three frames, which we record in self.frame, which is the total number of frames.

Overloaded function update

Next, let’s take a look at the update code.

 def update(self):

        if self.count < self.frame-1:

            self.count + = 1

        else:

            self.count = 0

        self.image = self.main_image.subsurface([self.count*self.single_w, 0, self.single_w,self.single_h])

Update is an overloaded function. In fact, in the update function, it is necessary to determine the frame number, current loop count, etc. However, in order to make it easier for you to feel what the code does, I directly use self.count to count the number of frames.

After entering the function, we use self.count to compare the total number of frames with self.frame. If the number of frames is not enough to switch, add 1, otherwise set to 0. After the judgment is completed, we change the image into the content of the next frame.

Among them, subsurface means passing in a rect value, copying the surface object of this value to the image object, and presenting it.

At this time, we need to put these contents into the group.

exp = explode('explode.png', 3, 262,262, (100,100))
group = pygame.sprite.Group()
group.add(exp)

First of all, exp is the object of the explode class we defined. The contents we pass in are the picture, the number of frames, the width of a single frame, and the height of a single frame, and the sprite is displayed on the screen.

Subsequently, we define an object called group and fill the group with the exp object. Then, we write a bunch of code inside the big loop.

group.update()
    group.draw(screen)

This update calls the exp.update function. draw is to draw the content we filled in the group on the screen. Since the animation cannot be displayed in the article, I will not include the picture in the article.

In the sprite class, in addition to the presentation of animation, we also create collision effects. This is a more complex level. In the following content, I will present the implementation of collision in a simple way.

Of course, the Sprite class also has more advanced uses, in addition to collision, there is also the concept of Layer. In fact, there is no concept of order when adding sprites to a group, so it is not clear which sprite comes first and which comes last. At this time, you can use classes such as OrderUpdates and LayerUpdates, among which LayerUpdates has many methods that can be called, so that There will be a layered concept.

Summary

In this section, you need to remember these key points.

The deformation, scaling of elves and some simple operations on elves in pygame.

You can intuitively feel that it is very convenient to use the elf class and the group class together. In other words, we ignore these methods of blit, and update and draw can be done directly in the group at once. A lot of work.

It is not impossible if we write the sequence frame animation function of the sprite separately, but you may need to write quite a lot of code to replace the work of the Sprite and group classes.