一些pygame的小东西

之前就有学过一部分的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_surfacepython.display.setmode()返回的surface对象
image当前显示的动画帧帧
master_image读取的包含全部动画帧序列图
rect四个元素的元组,分别表示动画帧绘制在target_surface的位置x,y,以及一个动画帧的宽,高
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

从加载图片里面就可以看出来初始化中一些变量的作用都是啥。感觉有点意义的地方也就是last_frame,这个数量其实是我们计算出来的。。。通过计算传入序列图和一个帧的大小计算。。(感觉合理,但总觉得应该会更加好用一些来着。。。)

    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

这一段内容就是切割序列图获得准备现实的动画帧,给image变量,然后的一步是把交接当前帧序号。

  • 但其实我还是不知道为啥每次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
        # 。。。
  • current_time是作为输入参数,在循环中使用group的update来调用我们的sprite中的update,而这个参数的内容就是一个数字。从pygame.init()被调用开始进行计时,过了多少毫秒。而这个数字又是通过调用pygame.time.get_ticks()得到。
  • 而在这个update函数中就一个默认50的参数就是决定刷新频率的一点。通过看函数内容就知道每次进行update都要至少经过50毫秒。当设置成1000的时候就可以观察到确实是在每一秒更新一次动画帧。

此外还有一个更加显示的控制帧率的方法。

framerate = pygame.time.Clock()
# 。。。
while True:
    framerate.tick(4)
  • pygame.time.Clock()的作用描述为create an object to help track time。
  • 在循环体中有一句framerate.tick(4)。这个函数在文档中的描述为每一帧都应该被调用一次,返回值为距离上一帧经过了多少毫秒。但如果有参数传入,则作用为限定程序运行帧率不会超过给定数值。比如我在其中填入了数值4,画面也确实是每一秒更新4个动画帧。
  • 同时,他也会限制这个循环在1秒内只会运行4次。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值