窗口类
这篇文章我们来讲讲_update_world
函数,先上代码:
class Window(...):
...
def _update_world(self, dt):
# 得到当前的速度
speed = Settings.walking_speed
# == A ==
d = dt * speed
# 获取移动的3维矢量(vector3)
# 一个3维矢量是 x y z 坐标都位于-1到1之间的有3个值元组(tuple)
dx, dy, dz = self.get_motion_vector()
dx, dy, dz = dx * d, dy * d, dz * d
# 重力效果
self.dy -= dt * Settings.gravity
# 不让玩家下落得太快
self.dy = max(self.dy, -Settings.terminal_velocity)
dy += self.dy * dt
x, y, z = self.position
# 碰撞检测,到时候会好好讲讲这个函数
x, y, z = self.collide((x + dx, y + dy, z + dz), Settings.player_height)
self.position = (x, y, z)
A:这里为什么要把速度都乘上d
呢?大家看d = dt * speed
,speed
是定义在Settings
类中的,为5.0
,记得吗?忘了的话快看看第二篇。那这个dt
又是什么呢?第九篇讲过,这个dt
是由update
函数传入的,在update
函数里为dt / m
,m
等于8,这里的dt
是由pyglet
传入的,表示上一次调用和这一次调用的间隔。第九篇中有这么一行代码:
class Window(...):
def __init__(...):
...
pyglet.clock.schedule_interval(self.update, 1.0 / Settings.ticks_per_sec)
这就是说,如果你的计算机没有延迟的话,应该是每秒调用Settings.ticks_per_sec
次update
函数,Settings.ticks_per_sec
为60
,也就是每隔1/60
秒就要调用一次update
函数,那么两次调用的间隔就是1/60
,单位为秒。在传入_update_world
函数时被除了8
,就成了1/480
。
有的人可能会想,那直接写1/480
就行了,为什么还要弄得这么复杂呢?这其实是为了考虑另外一种情况。如果我的计算机不是毫无延迟的。这个时候因为产生了延迟,调用的间隔就变长了,单位时间内调用的次数减少了,相应的dt
就要增加,这样才能不管有没有延迟移动的速度都是一样的。
这次讲解的内容比较多,大家可以再好好研究一下这种写法。如果有不懂欢迎评论。最后,点一个赞吧~