时间控制

在最小应用示例的最后,使用了pyglet.app.run()来启动了整个应用,并使应用进入了主循环来处理相应的事件。但是对于游戏来说,应用并不总是立刻对用户的输入产生响应的,而是采用了基于时间的处理机制,换句话说可以称为FPS控制。

如果不采用FPS控制,任由应用对用户的输入进行实时响应,那么整个画面就会失去流畅的感觉,造成忽快忽慢的现象。所以采用基于时间的处理机制就显得十分重要。pyglet提供了pyglet.clock.schedule_interval(func, seconds)函数来定期的执行某个处理。例如:

def update(dt):
	pass

pyglet.clock.schedule_interval(update, 0.1)

传递给pyglet.clock.schedule_interval(func, seconds)的函数需要接收一个参数,即示例中的dt,用以控制函数的运行间隔。也就是函数自身可以控制其启动的绝对时间间隔,但是pyglet会按照计划定期的调用排入的函数,而并不管指定函数是否真正的完成了工作。一般情况下为了控制画面的帧速不会大于60 FPS,传递给schedule_interval()的时间间隔通常都为\(\frac{1}{60}\)。

如果要定期执行的任务不必控制运行频率,可以使用pyglet.clock.schedule(func)。这个函数会尽可能的反复调用指定函数,可能会造成较高的CPU占用。

另外一种定期执行任务的方式是pyglet.clock.schedule_once(func),这个函数会仅执行一次指定函数。

要使指定函数从定时任务中取消,可以使用pyglet.clock.unschedule(func)函数。这在用户进行一项输入后取消指定函数的执行,然后在进行其他输入后又恢复执行的动作中十分有用。

精灵控制技巧

对于第一次接触游戏开发的读者这里会接触一个新词汇:精灵。这是游戏中所有可以活动的物体的统称,一般用来指代图像物体。精灵是画面中始终随时间进行运动变化的物体,所以如何控制其动画状态和运动状态,是一个游戏中非常重要的控制内容。

前面示例中update(dt)函数接受的参数dt是一个时间分量。这个时间分量是pyglet根据实际调用生成的,是代表真实函数调用间隔时间的。所以可以在定时函数中采用\(d = v \times dt\)来计算精灵的移动距离,并且可以同理计算精灵的旋转、动画播放等参数。