游戏循环

Pyxen 以固定的每秒 30 帧运行你的游戏。你不需要编写主循环——定义两个函数,Pyxen 会为你调用它们。

start() 和 update()

def start():
    # called once, at the beginning
    pass

def update():
    # called every frame, 30 times per second
    pass

start() 是你设置世界的地方:生成实体、放置它们、配置场景。

update() 是你的游戏逻辑运行的地方:读取输入、移动实体、检查条件、更新状态。每次调用 update() 之后,引擎会渲染该帧。

固定帧率

每一帧占用完全相同的时间:1/30 秒(约 33ms)。这意味着:

如果你偏好基于时间的运动,仍然可以使用 time.dt(增量时间),但它始终是 1/30。

帧顺序

每一帧,Pyxen 按以下顺序执行这些步骤:

  1. 输入 — 读取键盘、鼠标、触控和手柄状态
  2. update() — 你的代码运行
  3. 碰撞 — 引擎处理网格碰撞体并调用碰撞回调
  4. 渲染 — 引擎绘制所有可见实体

这意味着当你在 update() 中读取输入时,值是最新的。当你移动一个实体时,碰撞处理紧随其后。

碰撞回调

如果你在顶层定义了 on_hit_body 或 on_hit_tile,引擎会在碰撞阶段调用它们:

def on_hit_body(entity, other):
    # two grid bodies overlapped
    pass

def on_hit_tile(entity, tile):
    # a grid body hit a tilemap tile
    pass

这些在 update() 之后、渲染之前运行。

时间控制

pyxen.time 模块提供:

属性值用途
time.frame0, 1, 2, ...自启动以来的帧计数
time.dt0.0333...增量时间(始终为 1/30)
time.t0.0, 0.033, 0.066, ...经过的秒数
time.fps30每秒帧数

对于定时事件,你可以使用两种方式:

# Frame-based: fire every 60 frames (2 seconds)
if time.frame % 60 == 0:
    fire()

# Time-based: same thing
if int(time.t * 30) % 60 == 0:
    fire()

帧计数通常更简单、更可预测。