Clock
The Excalibur mainloop, the infinite update and draw cycle, is driven by the Clock.
Standard clock
The standard clock is the default, and runs continuously once started. The internal implementation uses the browser requestAnimationFrame()
to drive each game tick.
Limiting FPS
The FPS of the clock can be artificially limited in the Engine constructor, this can be useful to produce a consistent experience on many platforms or testing lower a framerate.
If no max is set, the FPS will be whatever the browser allows (usually display refresh rate)
For example, limiting to 30fps:
ts
constexampleGame = newex .Engine ({maxFps : 30});
ts
constexampleGame = newex .Engine ({maxFps : 30});
Scheduling tasks (also see Timer)
Instead of using the browser setTimeout()
the clock can be used to
schedule tasks that are tied to the Excalibur clock using Clock.schedule. This means they will respect when a game is stopped and not fire scheduled tasks.
ts
game .clock .schedule (() => {console .log ('Hello in 300ms');}, 300);
ts
game .clock .schedule (() => {console .log ('Hello in 300ms');}, 300);
Clearing scheduled tasks
You can also cancel scheduled tasks by saving the ID returned from schedule and passing it to clearSchedule:
ts
consttaskId =game .clock .schedule (() => {console .log ('This will never be logged');}, 500);// Cancel the scheduled taskgame .clock .clearSchedule (taskId );
ts
consttaskId =game .clock .schedule (() => {console .log ('This will never be logged');}, 500);// Cancel the scheduled taskgame .clock .clearSchedule (taskId );
Timing parameter
The schedule
method accepts an ScheduledCallbackTiming enum an optional third parameter that specifies when in the game loop the callback should execute. This allows precise control over when your scheduled tasks run relative to the game's update cycle.
ts
// Schedule a callback to run before the frame is processed (default)game .clock .schedule (() => {console .log ('Running before the frame');}, 200, 'preframe');// Schedule a callback to run after the frame is processedgame .clock .schedule (() => {console .log ('Running after the frame');}, 200, 'postframe');
ts
// Schedule a callback to run before the frame is processed (default)game .clock .schedule (() => {console .log ('Running before the frame');}, 200, 'preframe');// Schedule a callback to run after the frame is processedgame .clock .schedule (() => {console .log ('Running after the frame');}, 200, 'postframe');
Available timing options:
'preframe'
(default): Executes before the frame update and draw cycle'postframe'
: Executes after the frame update and draw cycle'preupdate'
: Executes before the update logic'postupdate'
: Executes after the update logic'predraw'
: Executes before drawing'postdraw'
: Executes after drawing
Test clock
The test clock allows single stepping of each clock tick, which can be useful for debugging and unit testing.
Stepping & Running the clock
ts
consttestClock =game .debug .useTestClock ();// Single Step as if we are running 60fpstestClock .step (16.6);// Multiple steps at once, for example 100 steps at 60fpstestClock .run (100, 16.6);// to switch back to the standard clockgame .debug .useStandardClock ();
ts
consttestClock =game .debug .useTestClock ();// Single Step as if we are running 60fpstestClock .step (16.6);// Multiple steps at once, for example 100 steps at 60fpstestClock .run (100, 16.6);// to switch back to the standard clockgame .debug .useStandardClock ();