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


鼠标|python游戏引擎ppb介绍(3)精灵属性与鼠标事件
文章插图
精灵的属性
上节课提到,每个精灵载入时默认的大小是1个单位,这个单位默认是窗口宽度的1/25,如果我们想某个精灵大一些,我们可以通过设置它的size属性来实现。
比如我们把下面的软体动物大小设置为3,上面的靶子大小设置为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)精灵属性与鼠标事件
鼠标|python游戏引擎ppb介绍(3)精灵属性与鼠标事件
文章插图