“This is the sixth day of my participation in the Gwen Challenge in November. Check out the details: The Last Gwen Challenge in 2021.”

This series of columns will reinforce your Knowledge of Python by constantly writing games.

This column aims to sharpen your knowledge of Python while quickly mastering PyGame, so come along.

Sprite module, Sprite object

Sprite classes and Sprite objects. The first thing to look at is what properties and methods are provided in the Sprite class.

print(dir(pygame.sprite))
Copy the code
['AbstractGroup'.'DirtySprite'.'Group'.'GroupSingle'.'LayeredDirty'.'LayeredUpdates'.'OrderedUpdates'.'Rect'.'RenderClear'.'RenderPlain'.'RenderUpdates'.'Sprite'.'__builtins__'.'__cached__'.'__doc__'.'__file__'.'__loader__'.'__name__'.'__package__'.'__spec__'.'collide_circle'.'collide_circle_ratio'.'collide_mask'.'collide_rect'.'collide_rect_ratio'.'from_surface'.'get_ticks'.'groupcollide'.'pygame'.'spritecollide'.'spritecollideany'.'truth']
Copy the code

There’s not much to go on, but the Sprite class is what I’m going to focus on.

To view the properties and methods of this class, see the following listing:

['__class__'.'__delattr__'.'__dict__'.'__dir__'.'__doc__'.'__eq__'.'__format__'.'__ge__'.'__getattribute__'.'__gt__'.'__hash__'.'__init__'.'__init_subclass__'.'__le__'.'__lt__'.'__module__'.'__ne__'.'__new__'.'__reduce__'.'__reduce_ex__'.'__repr__'.'__setattr__'.'__sizeof__'.'__str__'.'__subclasshook__'.'__weakref__'.'add'.'add_internal'.'alive'.'groups'.'kill'.'layer'.'remove'.'remove_internal'.'update']
Copy the code

List the key methods (the default method is really not many, in the use of more need to expand)

  • update(): methods for controlling the behavior of Sprite objects. This method does not have any implementation in the base class and needs to be overridden.
  • add()Add the Sprite object to the group;
  • remove()Sprite objects are removed from the group;
  • kill(): Delete the Sprite object from all groups;
  • groups(): returns all groups of Sprite objects;
  • alive(): Determines whether the Sprite method is still in the group.

The wizard diagram is dynamically switched

First look at the final effect, code learning.

Use the following material pictures, you can directly save to the local, or go to the Internet to search wizard map resources. Sprite map is to synthesize multiple pictures to a picture, write code without loading pictures one by one, the advantage is fast loading pictures. Sprite map resources can be downloaded from the following website:

www.aigei.com/game2d/ www.6pea.com/ www.6m5m.com/ www.spriters-resource.com/ opengameart.org/ openclipart.org/

Sprite figure in use, can be part of the area of the display, the code is as follows:

import sys

import pygame

pygame.init()
pygame.display.set_caption("Sprite map partial display")
screen = pygame.display.set_mode([500.500])
clock = pygame.time.Clock()
fps = 60
my_sprite = pygame.image.load('./imgs/guofurong.png').convert_alpha()

while True:
    clock.tick(fps)
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            sys.exit()
    screen.fill((12.200.180))
    screen.blit(my_sprite, (100.100))
    screen.blit(my_sprite, (100.100), (0.0.128.192))
    screen.blit(my_sprite, (300.100), (0.0.32.48))
    screen.blit(my_sprite, (300.200), (0.48.32.48))
    pygame.display.update()
Copy the code

Screen.blit (my_sprite, (100, 100), (0, 0, 128, 192)) blit has three parameters, which are the image, the coordinate point drawn, and the section drawn. This section is the equivalent of holding a transparent glass and sliding it over a picture. The transparent parts can be shown.

Pygame.display.set_mode () The prototype of this function is as follows. By default, it is recommended to pass only the first parameter, namely width and height. The operating system automatically selects the optimal parameter for the third parameter and generally does not set it. The second parameter represents the display type. If not set, the default window is displayed. The configurable window is described after the prototype.

set_mode(size=(0.0), flags=0, depth=0, display=0, vsync=0) -> Surface
Copy the code

The flags parameter values This parameter has the following selection, multiple values when using | segmentation.

  • pygame.FULLSCREEN: full screen display;
  • pygame.DOUBLEBUF: Double buffering mode, recommended andHWSURFACEorOPENGLUse together;
  • pygame.OPENGL: Create an OPENGL render window;
  • pygame.HWSURFACE: Hardware acceleration, effective in full screen;
  • pygame.RESIZABLE: Window can be adjusted size;
  • pygame.NOFRAME: The window has no borders and control buttons (maximize, minimize, close).

Use sprites to animate sprites

The core code is as follows, and the key part is explained with annotations.

import pygame

Declare a class that inherits from Sprite
class MySprite(pygame.sprite.Sprite) :
    def __init__(self) :
        Call the base class constructor
        pygame.sprite.Sprite.__init__(self)
        self.image = None
        self.master_image = None
        self.rect = None
        self.frame = 0
        self.frame_width = 1
        self.frame_height = 1
        self.first_frame = 0
        self.last_frame = 0
        self.columns = 1
        self.last_time = 0

    def load(self, filename, width, height, columns) :
        # loading images
        self.master_image = pygame.image.load(filename).convert_alpha()
        Crop the image to get the top line of the image
        self.master_image = self.master_image.subsurface((0.0.128.48))
        Get the width and height of the target area
        self.frame_width = width
        self.frame_height = height

        Get the rectangle area
        self.rect = 0.0, width, height
        # Add up 4 small pictures
        self.columns = columns

        rect = self.master_image.get_rect()
        print(rect)
        # get the last frame, here we get 3
        # with is passed in 32, so the total width is 128/32
        # height passes in 48, so the total height is 48
        self.last_frame = rect.width // width - 1

    def update(self, current_time, rate=60) :
        If the current time is greater than 60, perform the calculation
        if current_time > self.last_time + rate:
            self.frame += 1
            # greater than last frame, resets the number of frames
            if self.frame > self.last_frame:
                self.frame = self.first_frame
            # Count time
            self.last_time = current_time

        = 0,3,64,96
        frame_x = (self.frame % self.columns) * self.frame_width
        In this case, the change rule of y coordinate is 0
        frame_y = (self.frame // self.columns) * self.frame_height
        rect = (frame_x, frame_y, self.frame_width, self.frame_height)
        # print(rect)
        # Continue cropping the image
        self.image = self.master_image.subsurface(rect)

pygame.init()
screen = pygame.display.set_mode((300.300))
pygame.display.set_caption("My Sprite")
rate = pygame.time.Clock()

my_sprite = MySprite()
my_sprite.load("./imgs/guofurong.png".32.48.4)
groups = pygame.sprite.Group()
groups.add(my_sprite)

while True:
    rate.tick(60)
    ticks = pygame.time.get_ticks()

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

    screen.fill((44.169.240))
    groups.update(ticks)
    groups.draw(screen)
    pygame.display.update()
Copy the code

In the long case above, the core code is to calculate the coordinate position of each small graph. Another point is that in this case, I do not use blit() for drawing, but adopt the subsurface model. The essential difference between the two methods is that blit() draws the image directly on the surface of the surface object, and the subsurface model extracts the image first. Then draw the subsurfaces using sprite. draw, or group. draw.

So in this article Sprite group to draw the use, called groups.draw(screen) method.

I hope you learned something new in this extra column series.

If you have any questions, you can contact the eraser to solve them. Let’s play games together. The amount of practice for this column is about 1 hour every day.