Skip to content

Suki Core

Rory Duncan edited this page Sep 22, 2018 · 6 revisions

Suki module

Usage

import { suki, events, SubSystem } from "@roryduncan/suki";

Exports

The suki module has three exports:

  • suki

    An instance of the Suki class. Suki class is not exported, as it's intentionally instantiated and exported to prevent confusion and duplication.

  • events

    A 'enum' that for each built-in event that suki will emit. Custom events won't be added to events. See "Event Lifecycle" below for more details"

  • SubSystem

    A mixin class for extending Suki.js. You can use SubSystem to easily create a class the hooks into the event lifecycle of suki.js

Event Lifecycle

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.READY

    Emitted when the document, and subsequently, suki is able to start the game loop.

  • event.START

    Emitted 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.STOP

    Emitted after the suki.stop() has been called, and the main game loop has been halted.

  • event.TICK

    Emitted 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.STEP

    Emitted 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.PRERENDER

    The 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.RENDER

    Emitted after prerender and before postrender events. In general, you should hook into this event to draw to the canvas.

  • event.POSTRENDER

    Emitted after the render event. Use as you see fit.

Using Events

An event emitter is attached to the suki module:

suki.events.on(string: eventname, callback);

Custom events

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>);

Extending suki core with SubSystem

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.

Usage

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)
  }  
  

Clone this wiki locally