之前就有学过一部分的pygame,前段时间还想着能用这东西来帮别人做一个毕业设计来着,事情可以不了了之,学习永不停止。
因为毕设内容是一个跑酷游戏,所以找了个github代码直接拿来看,并且很幸运找到了作者的日志,所以通篇引用这位老哥的内容(https://www.cnblogs.com/msxh/tag/python/),算是一个笔记。
sprite类
游戏开发中很常见的类,国内译做精灵,有一些游戏引擎也会以面向精灵(各种继承来的类)编程来体现这一点。
最初我以为是这个类为我们做了把图片分割成一个个动画帧这些操作,我们只需要传入图片,设定一个帧大小就可以了。但是代码告诉我,切割帧,然后选择选择要画出来的动画帧,这些操作都是我们自己来做的。。(向来不喜欢进行图片操作,真的很麻烦啊。。)
def __init__(self, target):
pygame.sprite.Sprite.__init__(self)
self.target_surface = target
self.image = None
self.master_image = None
self.rect = None
self.topleft = 0,0
self.frame = 0
self.old_frame = -1
self.frame_width = 1
self.frame_height = 1
self.first_frame = 0
self.last_frame = 0
self.columns = 1
self.last_time = 0
成员 | 意义 |
---|---|
target_surface | python.display.setmode()返回的surface对象 |
image | 当前显示的动画帧帧 |
master_image | 读取的包含全部动画帧序列图 |
frame | 当前帧的序号 |
old_frame | 上一帧的序号 |
frame_width | 一个动画帧宽度 |
frame_height | 一个动画帧的高度 |
first_frame | 首个动画帧编号,为0 |
last_frame | 最后一个动画帧编号,为总数-1 |
columns | 序列图有多少列动画帧 |
last_time | 后续会用到的更新动画帧时间 |
def load(self, filename, width, height, columns):
self.master_image = pygame.image.load(filename).convert_alpha()
self.frame_width = width
self.frame_height = height
self.rect = 0,0,width,height
self.columns = columns
rect = self.master_image.get_rect()
self.last_frame = (rect.width // width) * (rect.height // height) - 1
def update(self, current_time, rate=50):
# 。。。帧数解释内容。
if self.frame != self.old_frame:
frame_x = (self.frame % self.columns) * self.frame_width
frame_y = (self.frame // self.columns) * self.frame_height
rect = ( frame_x, frame_y, self.frame_width, self.frame_height )
self.image = self.master_image.subsurface(rect)
self.old_frame = self.frame
- 但其实我还是不知道为啥每次update都会使用image来更新动画帧,我也试过了只要在update里面把那个image读取另外的图片就会显示读取的其他图片。每一个精灵的绘制帧应该是draw()函数,但是不能重写这个函数,所以只能在update里面进行部分处理。
- 说到底这个动画帧基本还是全部靠程序员,每一帧显示啥,程序设定为多少帧,把精灵序列图切割为动画帧,这些操作都是自己写入了类中。自由度很高。。但是真的好不智能啊。。。
帧数控制
每个sprite都应该有一个update函数用来进行自我更新,当是看的时候就在疑惑pygame提供了什么机制来控制帧率,在文章中也只是提了要这样那样进行配置,在自己改了一些东西试一试之后有了一些理解。
def update(self, current_time, rate=50):
if current_time > self.last_time + rate:
self.frame += 1
if self.frame > self.last_frame:
self.frame = self.first_frame
self.last_time = current_time
# 。。。
此外还有一个更加显示的控制帧率的方法。
framerate = pygame.time.Clock()
# 。。。
while True:
framerate.tick(4)