欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

python游戏引擎ppb介绍(3)精灵属性与鼠标事件

程序员文章站 2022-07-12 23:34:54
...

精灵除了可以通过多帧形成一种动画效果之外,还必须可以在屏幕上运动,两种典型的运动方式是转动和平移,通过控制精灵的属性就可以实现。精灵的运动应该能够由用户来互动操作,这一机制是通过响应事件来实现的。

python游戏引擎ppb介绍(3)精灵属性与鼠标事件

精灵的属性

上节课提到,每个精灵载入时默认的大小是1个单位,这个单位默认是窗口宽度的1/25,如果我们想某个精灵大一些,我们可以通过设置它的size属性来实现。

比如我们把下面的软体动物大小设置为3,上面的靶子大小设置为2

class Blob(ppb.Sprite):

    image = Animation("blob_{0..6}.png", 10)

    size=3



class Target(ppb.Sprite):

    size=2

 

当然,精灵的位置也必须做响应调整,否则就会挤在一起了。

def setup(scene):

    scene.add(Blob(pos=(0, -3.5)))

    for x in range(-6, 7, 3):

       scene.add(Target(position=ppb.Vector(x, 3)))

 

这个setup函数,也是初始化函数,在调用时设定这个初始化函数,系统会在打开游戏窗口前首先执行这个函数,进行布局。

python游戏引擎ppb介绍(3)精灵属性与鼠标事件

刷新事件

注意看上面的动图,靶子以稳定的速度转动,而Blob以则始终盯住鼠标转动。我们先看靶子的运动是怎么实现的。

我们给靶子类中增加一个属性speed代表每秒转动的角度和一个函数以响应刷新事件on_update)。

class Target(ppb.Sprite):

    speed= 50

    size=2

    def on_update(self, event, signal):

       self.rotation-=self.speed* event.time_delta

 

刷新事件(on_update)有三个参数,第一个参数self代表自身对象,这是对象函数的共同特征;第二个参数event,代表事件信息;最后一个signal参数,后面的课程中会讲到。

事件信息有多个内容:这里我们用的是时间差,具体含义是自从上次响应此事件后又过了多少时间(以秒为单位)。这个信息的设计特别好,因为系统运行的各种具体情况,一般来说,两次函数调用很难保证时间间隔相同。有了这个信息,让我们可以方便地设计出帧数稳定的动态效果。

我们来看看事件中做了什么事情呢?

修改了自身的rotation属性,rotation代表精灵当前的旋转角度,减法方向是逆时针运动,加法方向是顺时针运动。所以这样写的代码,就让精灵持续地逆时针转动起来了。

如果我们想改变速度,只需调整speed参数即可。

鼠标事件

下一步来看Blob的鼠标事件

class Blob(ppb.Sprite):

    image = Animation("blob_{0..6}.png", 10)

    size=3



    def on_mouse_motion(self, event, signal):

        p1= (event.position- self.position).normalize()

        self.rotation= -90+ppb.Vector(1,0).angle(p1)

 

鼠标事件的on_mouse_motion,代表鼠标位置改变时所触发的事件。此外,还有鼠标点击时触发的事件,下节课介绍。

我们注意到,所有的事件,参数基本结构都是一样的。而event里面的具体信息则有差别。比如这个鼠标移动事件,我们关心的就是鼠标所在的位置信息。

仍然是通过设置精灵的rotate属性实现转动。这里用到了向量操作,可能有朋友对向量操作的印象已经不深了,在这里复习一下向量计算

p1是一个方向向量,用位置相减,即代表Blob的位置指向鼠标所在位置的方向。normalize()函数的作用是归一化,即将向量的模长变成1(这步其实可以省略)。

然后通过angle()函数,获取这个方向向量与0方向(x轴正方向)的夹角。

精灵方向角的设置,以x轴正方向为0度,默认图片的角度是向上的,也就是90度。所以为了让精灵面向鼠标,这里还必须逆时针转向90(即-90°)。

完整代码

代码中用到的资源,可以从前一节课程中内置的图片下载。

其他部分,与前一节课相比没有变化,这里再贴一下完整版。

import ppb

from ppb.features.animation import Animation



class Blob(ppb.Sprite):

    image = Animation("blob_{0..6}.png", 10)

    size=3



    def on_mouse_motion(self, event, signal):

        p1= (event.position- self.position).normalize()

        self.rotation= -90+ppb.Vector(1,0).angle(p1)



class Target(ppb.Sprite):

    speed= 50

    size=2

    def on_update(self, update_event, signal):

       self.rotation-=self.speed* update_event.time_delta





def setup(scene):

    scene.add(Blob(pos=(0, -3.5)))

    for x in range(-6, 7, 3):

       scene.add(Target(position=ppb.Vector(x, 3)))



ppb.run(setup=setup,resolution=(800, 600))

 

python游戏引擎ppb介绍(3)精灵属性与鼠标事件