《pygame游戏开发实战指南》第八节 Sprite类和Group类

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

项目代码下载地址: https://github.com/la-vie-est-belle/pygame_codes


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()

运行结果如下:
示例代码8-1运行结果

代码解释如下:
#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()

运行结果如下:
示例代码8-2运行结果

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

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

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


8.3 小结

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


如果你喜欢笔者的这部专栏,可以给笔者一些打赏,或者通过购买一些项目来支持作者,非常感谢!

微信支付   支付宝   微店
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

la_vie_est_belle

谢谢支持

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值