-
Notifications
You must be signed in to change notification settings - Fork 0
Suki Core
import { suki, events, SubSystem } from "@roryduncan/suki";
The suki module has three exports:
-
sukiAn instance of the
Sukiclass.Sukiclass is not exported, as it's intentionally instantiated and exported to prevent confusion and duplication. -
eventsA 'enum' that for each built-in event that
sukiwill emit. Custom events won't be added toevents. See "Event Lifecycle" below for more details" -
SubSystemA mixin class for extending Suki.js. You can use
SubSystemto easily create a class the hooks into the event lifecycle ofsuki.js
The event lifecycle - i.e. which events happen when, and how you can hook into them.
You can access all events from the exported events enum. Knowing the lifecycle will help you to utilize these events usefully.
-
event.READYEmitted when the document, and subsequently,
sukiis able to start the game loop. -
event.STARTEmitted after the
suki.start()has been called, and the main game loop has begun. Because this is called synchronously, it will likely be called before the first frame. -
event.STOPEmitted after the
suki.stop()has been called, and the main game loop has been halted. -
event.TICKEmitted for every game tick of the game loop. Any events listening to this event should be aware of their highly likely cost to performance.
-
event.STEPEmitted for each gameloop step. A step occurs at a periodic rate related to the framerate. If you need more information, it's suggest you seek further reading about game loop steps.
-
event.PRERENDERThe first event emitted after a step. Render events may not be emitted 1:1 with each step: if a frame skip occurred renders will not happen (frame skipping). Happens before a render. Use as you see fit.
-
event.RENDEREmitted after prerender and before postrender events. In general, you should hook into this event to draw to the canvas.
-
event.POSTRENDEREmitted after the render event. Use as you see fit.
An event emitter is attached to the suki module:
suki.events.on(string: eventname, callback);The events is a fake enum -- really it's just an object with keys matching the event name values that suki expects.
With that knowledge you can add events simply by using the underlying event emitter:
suki.events.on("customevent", callback);
// some time later...
// suki.events.trigger("customevent", <eventdata>);For time when you need to create or extend suki js, it's suggested you use a SubSystem. This is especially true if you think you'll want to hook into many or all of the events of the event lifecycle.
SubSystems allow you to dynamically listen and unlisten to all suki.js events, via the .mount() and .unmount() methods.
The SubSystem export is an inheritable class mixin.
import { SubSystem } from "@roryduncan/suki";
class MyCustomClass extends SubSystem() {
}Note that Subsystem is executed in the above example. You can pass a class to inherit from if needed:
class SuperClass { ... }
class MyCustomClass extends SubSystem(SuperClass) {
}The class that extends SubSystem() is expected to overwrite virtual methods corrosponding to suki lifecycle events.
Add any of the following as methods of your class to then have them mounted or unmounted:
tick, step, preRender, render, postRender.
The core logic of .mount() and .unmount() is fairly clear:
mount() {
if (this.tick) suki.events.on(events.TICK, this.tick, this.data)
if (this.step) suki.events.on(events.STEP, this.step, this.data)
if (this.preRender) suki.events.on(events.PRERENDER, this.preRender, this.data)
if (this.render) suki.events.on(events.RENDER, this.render, this.data)
if (this.postRender) suki.events.on(events.POSTRENDER, this.postRender, this.data)
}
unmount() {
if (this.tick) suki.events.off(events.TICK, this.tick, this.data)
if (this.step) suki.events.off(events.STEP, this.step, this.data)
if (this.preRender) suki.events.off(events.PRERENDER, this.preRender, this.data)
if (this.render) suki.events.off(events.RENDER, this.render, this.data)
if (this.postRender) suki.events.off(events.POSTRENDER, this.postRender, this.data)
}