gibbon.js
Version:
Actor/Component system for use with pixi.js.
162 lines (117 loc) • 2.83 kB
text/typescript
import type { Actor } from './core/actor';
import { quickSplice } from './utils/array-utils';
import { Ticker } from 'pixi.js';
import type { Container } from 'pixi.js';
export interface ITicker {
start(): void;
stop(): void;
}
export interface IUpdater {
/**
*
* @param delta - time transpired in seconds.
*/
update(delta: number): void;
}
export class Engine implements IUpdater {
/**
* @property {Container} objectLayer
*/
_objectLayer?: Container;
get objectLayer() { return this._objectLayer }
set objectLayer(v: Container | undefined) {
this._objectLayer = v;
}
/**
* @property {Actor[]} objects
*/
readonly objects: Actor[];
/**
* @property {IUpdater[]} updaters - Updaters are for systems or objects with update
* functions that don't require complex Actors.
*/
readonly updaters: IUpdater[];
readonly ticker: Ticker;
constructor(ticker?: Ticker) {
this.objects = [];
this.updaters = [];
this.ticker = ticker ?? new Ticker();
this.ticker.add(this.update, this);
}
update() {
const sec = this.ticker.deltaMS / 1000;
const updaters = this.updaters;
for (let i = updaters.length - 1; i >= 0; i--) {
updaters[i].update(sec);
}
const objs = this.objects;
for (let i = objs.length - 1; i >= 0; i--) {
const obj = objs[i];
if (obj.isDestroyed === true) {
obj._destroy();
quickSplice(objs, i);
} else if (obj.active) obj.update(sec);
}
}
start() {
this.ticker.start();
}
stop() {
this.ticker.stop();
}
/**
* Add Actor to the engine.
* @param {Actor} obj
*/
add(obj: Actor) {
if (obj.isAdded) {
console.warn(`error: Actor already added to engine.`);
}
if (obj.clip != null && obj.clip.parent == null) {
this._objectLayer!.addChild(obj.clip);
}
obj._added();
this.objects.push(obj);
}
/**
*
* @param {IUpdater} sys
*/
addUpdater(sys: IUpdater) {
if (this.updaters.indexOf(sys) < 0) {
this.updaters.push(sys);
}
}
/**
*
* @param {IUpdater} sys
*/
removeUpdater(sys: IUpdater) {
const ind = this.updaters.indexOf(sys);
if (ind >= 0) {
this.updaters.splice(ind, 1);
}
}
/**
* Remove a Actor from the Engine.
* @param {Actor} obj
* @returns {boolean} true if object was removed.
*/
remove(obj: Actor): boolean {
const ind = this.objects.indexOf(obj);
if (ind < 0) return false;
this.objects.splice(ind, 0);
//this._objects[ind] = this._objects[ this._objects.length-1];
//this._objects.pop();
return true;
}
/**
* Destroy a game object.
* @param {Actor} obj
*/
destroy(obj: Actor) {
if (obj.isDestroyed !== true) {
obj.destroy();
}
}
}