记录时间
小矮人的 clock
模块允许您安排函数定期运行,或在将来一次性执行。
定期调用函数
中讨论过的 应用程序事件循环 部分中,pyglet应用程序通过进入应用程序事件循环::
pyglet.app.run()
一旦被调用,该函数直到应用程序窗口关闭后才会返回。这可能会让您想知道如何在应用程序运行时执行代码。
典型的应用程序只需要在三种情况下执行代码:
已生成用户输入事件(例如鼠标移动或按键)。在这种情况下,可以将适当的代码作为事件处理程序附加到窗口。
动画或其他依赖时间的系统需要更新对象的位置或参数。我们将其称为“周期性”事件。
经过了一段时间后,可能表示某个操作已超时,或者某个对话框可以自动关闭。我们会把这称为“一次性”事件。
要定期调用函数,例如,每0.1秒调用一次::
def update(dt):
# ...
pyglet.clock.schedule_interval(update, 0.1)
这个 dt ,或 delta time 参数提供自上次调用该函数以来经过的“挂钟”秒数(如果是第一个周期,则为调度该函数的时间)。由于延迟、负载和计时器不精确,这可能略大于或小于请求的间隔。请注意, dt 参数始终传递给预定函数,因此编写函数时,即使您不需要使用它,也要确保预期到它。
具有设定间隔的调度功能是动画、物理模拟和游戏状态更新的理想选择。Pyglet确保应用程序不会消耗超过按时执行预定功能所需的资源。
与其他工具包中常见的“限制帧速率”不同,只需将您的所有更新功能安排在应用程序或游戏所需的最短时间内即可。例如,大多数游戏不需要以超过60赫兹(每秒60次)的速度运行以获得难以察觉的流畅动画,因此给定的时间间隔 schedule_interval()
会是 1/60.0
(或更多)。
如果您正在编写基准测试程序,或者希望以尽可能高的频率运行,请使用 schedule 。这将尽可能频繁地调用该函数(并且可能会导致大量的CPU使用):
def benchmark(dt):
# ...
pyglet.clock.schedule(benchmark)
备注
默认情况下,pyglet窗口缓冲区交换与显示刷新率同步,因此,如果您正在运行基准测试,则可能还需要禁用vsync。
对于一次性事件,请使用 schedule_once()
**
def dismiss_dialog(dt):
# ...
# Dismiss the dialog after 5 seconds.
pyglet.clock.schedule_once(dismiss_dialog, 5.0)
要停止调用调度函数,包括取消周期函数,请使用 pyglet.clock.unschedule()
。如果您希望在用户提供某个输入时按计划开始运行某个函数,然后在收到另一个输入时取消该函数的计划,这可能很有用。
雪碧运动技术
如上所述,每个调度函数都会收到一个 dt 参数,给出自上一次调用以来经过的实际“挂钟”时间。该参数可用于数值积分。
例如,一个非加速粒子的速度 v
会在时间的变化中旅行一段距离 dt
。此距离的计算公式为 v * dt
。类似地,恒加速度下的粒子 a
会有一个速度的变化 a * dt
。
下面的示例演示了一种以每秒10像素的速度在屏幕上移动子画面的简单方法:
sprite = pyglet.sprite.Sprite(image)
sprite.dx = 10.0
def move_sprite(dt):
sprite.x += sprite.dx * dt
pyglet.clock.schedule_interval(move_sprite, 1/60.0) # update at 60Hz
对于简单的精灵移动来说,这是一种健壮的技术,因为无论计算机的速度或负载如何,速度都将保持恒定。
下表中给出了其他常见动画变量的一些示例。
动画参数
距离
速度
旋转
学位
每秒度数
职位
象素
每秒像素数
关键帧
帧编号
每秒帧数
显示帧速率
分析应用程序性能的一种简单方法是在应用程序运行时显示帧速率。将其打印到控制台并不理想,因为这将对性能产生严重影响。pyglet提供了 FPSDisplay
用于轻松显示帧速率的类::
fps_display = pyglet.window.FPSDisplay(window=window)
@window.event
def on_draw():
window.clear()
fps_display.draw()
默认情况下,帧速率将以半透明大字体绘制在窗口的左下角。请参阅 FPSDisplay
文档,以获取有关如何自定义它的详细信息,甚至完全显示另一个时钟值(如当前时间)。
用户定义的时钟
pyglet使用的默认时钟使用系统时钟来确定时间(即, time.time()
)。但是,可以创建单独的时钟,从而允许您使用另一个时间源。这对于实现与真实世界时间分开的“游戏时间”,或者同步到网络时间源或声音设备非常有用。
每一位 clock_*
函数是全局实例上的方法的别名 Clock
。您可以构造自己的子类或创建自己的子类 Clock
,然后它可以维护自己的时间表和帧速率计算。有关更多详细信息,请参阅类文档。