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类时,我们必须让自定义类拥有image和rect实例属性,属性名称也不能修改。请看下方代码片段。
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对象的image和rect属性用作参数。
示例代码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类的用法以及两者之间的关系。使用这两个类,我们可以让游戏代码结构更加清晰易懂,方便修改。
如果你喜欢笔者的这部专栏,可以给笔者一些打赏,或者通过购买一些项目来支持作者,非常感谢!



















