问小白 wenxiaobai
资讯
历史
科技
环境与自然
成长
游戏
财经
文学与艺术
美食
健康
家居
文化
情感
汽车
三农
军事
旅行
运动
教育
生活
星座命理

pygame游戏开发实战:Sprite类和Group类详解

创作时间:
作者:
@小白创作中心

pygame游戏开发实战:Sprite类和Group类详解

引用
CSDN
1.
https://m.blog.csdn.net/La_vie_est_belle/article/details/141181034

Sprite(精灵)是游戏中一个非常重要的概念。在游戏开发中,Sprite指的是一个可以移动、旋转或变换的二维图像,它负责管理游戏中的图像元素,使得开发者可以轻松地在游戏中创建各种动态效果和角色。pygame.sprite模块提供了Sprite类和Group类,两者关系密切,一般同时出现。Group其实就是Sprite的容器,可以让我们更加方便地管理各个Sprite对象。本节会详细介绍下这两个类。

8.1 Sprite

我们先来看下Sprite类的常见属性和函数。

image

image属性表示当前Sprite精灵显示的图像,该属性的值是Surface类型。

rect

rect属性表示当前Sprite精灵所在的矩形区域,该属性的值是Rect类型。

注:当自定义类继承Sprite类时,我们必须让自定义类拥有imagerect实例属性,属性名称也不能修改。请看下方代码片段。

class MySprite(pygame.sprite.Sprite):
    def __init__(self):
        super(MySprite, self).__init__()
        self.image = pygame.image.load('xxx.png')
        self.rect = self.image.get_rect()
update()

继承Sprite类后,我们可以重写这个函数,把Sprite对象的状态更新操作都放在这里。

注:Group类也有个update()函数,当某个Group对象调用了自己的update()函数时,就会触发所有被添加进来的Sprite对象的update()函数。

add(*groups)

将当前Spite对象添加到指定的Group对象中。一个Sprite对象可以同时被添加到多个Group对象中。

remove(*groups)

从指定的Group对象中删除当前Spite对象。

kill()

把当前Spite对象从所有的Group对象中删除。

alive()

判断当前Spite对象是否有被添加到任何一个Group对象中,有的话就返回True,否则返回False

groups()

返回一个添加了当前Spite对象的Group对象列表。

示例代码8-1演示了Sprite类的用法。

import sys
import pygame

class Dino(pygame.sprite.Sprite):               # 1
    def __init__(self):
        super(Dino, self).__init__()
        self.image = pygame.image.load('dino_start.png').convert_alpha()
        self.rect = self.image.get_rect(topleft=(80, 450))

        self.speed = 1

    def draw(self, surface):
        surface.blit(self.image, self.rect)

    def update(self):
        self.rect.x += self.speed
        if self.rect.right >= 1100 or self.rect.left <= 0:
            self.speed = -self.speed
            self.image = pygame.transform.flip(self.image, True, False)

def main():
    pygame.init()
    clock = pygame.time.Clock()                 # 2

    screen = pygame.display.set_mode((1100, 600))
    pygame.display.set_caption('Dino Runner')

    icon = pygame.image.load('icon.png')
    pygame.display.set_icon(icon)

    land = pygame.image.load('land.png').convert_alpha()
    land_rect = land.get_rect()
    land_rect.y = 520

    dino = Dino()                               # 3

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

        screen.fill((255, 255, 255))
        screen.blit(land, land_rect)
        
        dino.draw(screen)                       # 4
        dino.update()

        pygame.display.flip()
        clock.tick(60)

if __name__ == '__main__':
    main()

运行结果如下:

代码解释如下:
#1 定义一个Dino类,继承Sprite类,然后指定了必要的image属性和rect属性。speed属性表示小恐龙的移动速度。draw()函数是自定义的,在该函数中,我们让这个小恐龙显示在了传入的Surface对象上。我们还重写了update()函数,让小恐龙不断的向左或向右移动。pygame.transform.flip()函数用来翻转图片,其参数解释如下。

flip(surface, flip_x, flip_y)
  • surface: 要翻转的Surface对象。
  • flip_x: bool类型,是否水平翻转。
  • flip_y: bool类型,是否垂直翻转。

#2 通过创建一个Clock对象,开发者可以精确地控制游戏循环的速度,确保游戏在不同计算机上以相同的速度运行,从而提供一致的游戏体验。Clock对象的tick()函数可以用来设置游戏帧率,tick(60)就表示将游戏帧率设置为60帧。

#3 实例化一个Dino对象。

#4 调用draw()函数将小恐龙显示在屏幕上,调用update()方法更新小恐龙的状态。

8.2 Group

现在我们来看下Group类的常用函数。

sprites()

返回一个列表,其中包含所有被添加进来的Sprite对象。

copy()

复制当前Group对象,返回一个新的Group对象,这个Group对象包含所有的原始的Sprite对象。

add(*sprites)

添加任意数量的Sprite对象,已经添加过的无法再被添加。

remove(*sprites)

移除任意数量的Sprite对象。

has(*sprites)

判断是否包含某个或某些Sprite对象,是的话返回True

update()

会调用所有被添加进来的Sprite对象的update()函数。

draw(surface)

把所有Sprite对象绘制到指定的Surface对象上。该函数就是调用了Surface对象的blit()函数,并将Sprite对象的imagerect属性用作参数。

示例代码8-2演示了Group类的用法。

import sys
import pygame

class Dino(pygame.sprite.Sprite):
    def __init__(self):
        super(Dino, self).__init__()
        self.image = pygame.image.load('dino_start.png').convert_alpha()
        self.rect = self.image.get_rect(topleft=(80, 450))

        self.speed = 1

    def draw(self, surface):
        surface.blit(self.image, self.rect)

    def update(self):
        self.rect.x += self.speed
        if self.rect.right >= 1100 or self.rect.left <= 0:
            self.speed = -self.speed
            self.image = pygame.transform.flip(self.image, True, False)

class Bird(pygame.sprite.Sprite):               # 1
    def __init__(self, pos):
        super(Bird, self).__init__()
        self.image = pygame.image.load('bird.png').convert_alpha()
        self.rect = self.image.get_rect()
        self.rect.center = pos

        self.speed = 1

    def update(self):
        self.rect.y += self.speed
        if self.rect.top >= 300 or self.rect.bottom <= 0:
            self.speed = -self.speed

def main():
    pygame.init()
    clock = pygame.time.Clock()

    screen = pygame.display.set_mode((1100, 600))
    pygame.display.set_caption('Dino Runner')

    icon = pygame.image.load('icon.png')
    pygame.display.set_icon(icon)

    land = pygame.image.load('land.png').convert_alpha()
    land_rect = land.get_rect()
    land_rect.y = 520

    dino = Dino()

    bird_group = pygame.sprite.Group()          # 2
    for i in range(5):
        bird = Bird((80+i*220, i*10))
        bird_group.add(bird)

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

        screen.fill((255, 255, 255))
        screen.blit(land, land_rect)

        dino.draw(screen)
        dino.update()

        bird_group.draw(screen)                 # 3
        bird_group.update()

        pygame.display.flip()
        clock.tick(60)

if __name__ == '__main__':
    main()

运行结果如下:

代码解释如下:
#1 定义一个Bird类,继承Sprite类。这个Bird类在实例化的时候接收一个pos参数,用来指定图片的中心位置。

#2 实例化一个Group对象,并通过add()函数将5个Bird对象添加了进去。

#3 调用draw()函数将所有Bird对象绘制到屏幕上。调用update()函数更新所有Bird对象的状态。

8.3 小结

本节我们了解了Sprite类和Group类的用法以及两者之间的关系。使用这两个类,我们可以让游戏代码结构更加清晰易懂,方便修改。

© 2023 北京元石科技有限公司 ◎ 京公网安备 11010802042949号