gummworld2.gameclock (version $Id: gameclock.py 428 2013-08-28 05:43:47Z stabbingfinger@gmail.com $) | index c:\cygwin64\home\bw\dev\python\dist\gummworld2\gamelib\gummworld2\gameclock.py |
gameclock.py - Game clock for Gummworld2.
GameClock is a fixed time-step clock that keeps time in terms of game
time. It will attempt to keep game time close to real time, so if an
interval takes one second of game time then the user experiences one
second of real time. In the worst case where the CPU cannot keep up with
the game load, game time will subjectively take longer but still remain
accurate enough to keep game elements in synchronization.
GameClock manages time in the following ways:
1. Register special callback functions that will be run when they
are due.
2. Schedule game logic updates at a constant speed, independent of
frame rate.
3. Schedule frames at capped frames-per-second, or uncapped.
4. Invoke a pre-emptive pause callback when paused.
5. Schedule miscellaneous items at user-configurable intervals.
6. Optionally sleep between schedules to conserve CPU cycles.
7. Gracefully handle corner cases.
Note the Python Library docs mention that not all computer platforms'
time functions return time in fractions of a second. This module will not
work on such platforms.
USAGE
Callback:
clock = GameClock(
update_callback=update_world,
frame_callback=draw_scene,
pause_callback=pause_game)
while 1:
clock.tick()
Special callbacks can be directly set and cleared at any time:
clock.update_callback = my_new_update
clock.frame_callback = my_new_draw
clock.pause_callback = my_new_pause
clock.update_callback = None
clock.frame_callback = None
clock.pause_callback = None
Scheduling miscellanous callbacks:
def every_second_of_every_day(dt):
"..."
clock.schedule_interval(every_second_of_every_day, 1.0)
Callbacks can be any kind of callable that accepts the callback signature.
The update_callback receives a single DT argument, which is the time-step
in seconds since the last update.
The frame_callback receives a single INTERPOLATION argument, which is the
fractional position in time of the frame within the current update time-
step. It is a float in the range 0.0 to 1.0.
The pause_callback receives no arguments.
User-defined interval callbacks accept at least a DT argument, which is
the scheduled item's interval, and optional user-defined arguments. See
GameClock.schedule_interval.
DEPRECATIONS
Old Style Game Loop
Use of the old style game loop is deprecated. Don't do this anymore:
if clock.update_ready:
update(clock.dt_update)
if clock.frame_ready:
draw(clock.interpolate)
The old style game loop will work on sufficiently fast hardware. Timekeeping
will break on slow hardware that cannot keep up with a heavy workload. This is
because the old style ignores the cost of the frame routine. By using callbacks
instead, cost is factored into the frame scheduling and overloading the CPU has
fewer negative side effects.
The update_ready and frame_ready public attributes have been removed.
CREDITS
The inspiration for this module came from Koen Witters's superb article
"deWiTTERS Game Loop", aka "Constant Game Speed independent of Variable FPS"
at http://www.koonsolo.com/news/dewitters-gameloop/.
The clock was changed to use a fixed time-step after many discussions with
DR0ID, and a few readings of
http://gafferongames.com/game-physics/fix-your-timestep/.
Thanks to Koen Witters, DR0ID, and Glenn Fiedler for sharing.
Pythonated by Gummbum. While the builtin demo requires pygame, the module
does not. The GameClock class is purely Python and should be compatible with
other Python-based multi-media and game development libraries.
Modules | ||||||
|
Classes | ||||||||
|
Data | ||
__all__ = ['GameClock'] __author__ = 'Gummbum, (c) 2011-2014' __version__ = '$Id: gameclock.py 428 2013-08-28 05:43:47Z stabbingfinger@gmail.com $' |
Author | ||
Gummbum, (c) 2011-2014 |