Часы и движение
Часы pyglet
Игровой цикл в pyglet крутит pyglet.app.run(). Чтобы что-то происходило каждый кадр, функцию ставят в расписание:
def update(dt):
ball.x += 200 * dt # 200 пикселей в секунду
pyglet.clock.schedule_interval(update, 1 / 60) # примерно 60 раз в секунду
dt — сколько секунд на самом деле прошло с прошлого вызова. Компьютер может подтормаживать, и тогда dt больше. Если всегда умножать скорость на dt, объекты движутся с одинаковой скоростью на любом компьютере.
Разовые и повторяющиеся события
pyglet.clock.schedule_once(start_level, 3) # один раз через 3 секунды
pyglet.clock.schedule_interval(blink, 0.5) # каждые полсекунды
pyglet.clock.unschedule(blink) # снять с расписания
Функция, которую вызывают часы, всегда получает первым аргументом dt — даже если он ей не нужен.
Внутри функции можно снять её саму с расписания — так делают «мигни 5 раз и остановись».
Свои часы
pyglet.clock.Clock — отдельные часы. Им можно передать свою функцию времени — это удобно для проверки: время идёт только тогда, когда вы его двигаете.
now = [0.0]
clock = pyglet.clock.Clock(time_function=lambda: now[0])
clock.schedule_interval(blink, 0.5)
now[0] = 1.0
clock.tick() # выполнить всё, чему пора
Основные часы программы — pyglet.clock.get_default(); функции pyglet.clock.schedule_… работают именно с ними.
Фиксированный шаг
Для физики удобнее шаг постоянной длины, например 20 мс. Время кадра копят, а потом «тратят» целыми шагами:
STEP = 20 # мс
acc = 0
def update(dt):
global acc
acc += round(dt * 1000)
steps = 0
while acc >= STEP and steps < 5: # не больше 5 шагов за кадр
physics_step()
acc -= STEP
steps += 1
if acc >= STEP: # не успели — лишнее отбрасываем
acc %= STEP
Предел шагов защищает от «спирали смерти»: если физика не успевает, кадры становятся длиннее, шагов нужно ещё больше — и игра зависает навсегда.
Итог
pyglet.clock.schedule_interval(f, interval),schedule_once(f, delay),unschedule(f);- функция получает
dt; движение —скорость * dt; pyglet.clock.Clock(time_function=...)иtick()— свои часы;- фиксированный шаг: копить время, тратить целыми шагами, ограничить число шагов за кадр.