如何通过精灵图集实现动画
关注 1421
如何在 Pygame 中实现精灵动画,控制播放速度视频演示 YouTube如何在 Pygame 中实现精灵动画,控制播放速度视频演示 Bilibili
引言
因为 Pygame 没有直接提供与精灵动画相关的内置类,因此,需要开发人员自行编写代码实现动画效果。本文将根据图像文件的存储方式,介绍两种常见的动画实现方式。
方式一:载入多个图像文件实现动画
载入多个图像文件是一种相对简单的动画实现方式,每一个图像文件可对应动画中的一个帧。这一般需要调用image
模块的load
函数,所产生的Surface
对象会赋值给精灵对象的image
变量。
当然,严格意义上来说,下面的示例所实现的并不像动画,更像是状态的切换。
# 加载门开关状态的图像
img_closed = pygame.image.load('doors_leaf_closed.png').convert_alpha()
img_open = pygame.image.load('doors_leaf_open.png').convert_alpha()
class Door(pygame.sprite.Sprite):
def __init__(self, *groups):
super().__init__(*groups)
self.image = img_closed # 初始状态为关闭
self.rect = self.image.get_rect()
def update(self, keys):
if keys[pygame.K_SPACE]:
self.image = img_open # 按下空格键显示开门状态
else:
self.image = img_closed # 释放空格键显示关门状态
方式二:通过精灵图集实现动画
精灵图集一般包含了动画中的所有帧,因此,要完成一个动画只需要加载一个图像文件。这同样需要调用image
模块的load
函数,并调用所返回的Surface
对象的subsurface
方法,以获得多个子表面,每个子表面对应了精灵图集中的一个帧。之后,可在游戏循环或精灵的update
方法中,将不同的子表面赋值给精灵对象的image
变量。
subsurface
方法有三种形式,本文使用的是四个浮点数参数的一种,前两个浮点数确定子表面左上角在父表面中的坐标,后两个浮点数指定子表面的宽度和高度。
subsurface 方法返回的子表面
subsurface
方法返回的子表面与父表面共享像素数据,不会创建新的像素。你不需要对子表面调用convert_alpha
方法,因为,如何绘制像素通常取决于父表面。
在下面的示例中,由于没有控制子表面的切换速度,因此,宝箱的播放速度可能会很快。
# 加载精灵图集
sprite_sheet = pygame.image.load('chest_001.png').convert_alpha()
# 创建子表面列表
img_cs = [sprite_sheet.subsurface(pygame.Rect(i*16, 0, 16, 32)) for i in range(6)]
class Chest(pygame.sprite.Sprite):
def __init__(self, *groups):
super().__init__(*groups)
self.image_index = 0 # 当前帧索引
self.image = img_cs[self.image_index]
self.rect = self.image.get_rect()
def update(self):
self.image_index = (self.image_index + 1) % len(img_cs) # 循环播放
self.image = img_cs[self.image_index]
控制动画播放速度
如果游戏的帧率为60
,那么上面例子中的宝箱动画,每秒可播放10
次。为了降低动画的播放速度,可添加一些变量进行控制。
下面,为Chest
添加类变量WAIT
和变量wait
,用于控制子表面的切换时间间隔,在update
方法判断是否可以进行子表面的切换。
调整WAIT
的值可改变动画播放速度。
class Chest(pygame.sprite.Sprite):
WAIT = 5 # 每 5 帧切换一次动画帧
def __init__(self, *groups):
super().__init__(*groups)
self.wait = 0 # 帧计数器
# …
def update(self):
self.wait += 1
if self.wait >= self.WAIT:
self.wait = 0
self.image_index = (self.image_index + 1) % len(img_cs) # 循环播放
self.image = img_cs[self.image_index]
讲解视频
如何在 Pygame 中实现精灵动画,控制播放速度·YouTube如何在 Pygame 中实现精灵动画,控制播放速度·Bilibili