UNPKG

gibbon.js

Version:

Actor/Component system for use with pixi.js.

151 lines (110 loc) 3.89 kB
import { Component } from "../core/component"; import { quickSplice } from "../utils/array-utils"; import { Constructor } from "../utils/types"; import { Point } from 'pixi.js'; import { EngineEvent } from "../events/engine-events"; import { TPoint } from '../data/geom'; export class Transform extends Component { private readonly _position: Point = new Point(); private _rotation: number = 0; name?: string; get position(): Point { return this._position; } set position(v: Point) { this._position.set(v.x, v.y); } get x(): number { return this._position.x; } set x(x: number) { this._position.x = x; } get y(): number { return this._position.y; } set y(y: number) { this._position.y = y; } get rotation(): number { return this._rotation; } set rotation(v: number) { while (v > Math.PI) v -= 2 * Math.PI; while (v < -Math.PI) v += 2 * Math.PI; this._rotation = v; } get size() { return this._size; } get width() { return this._size.x } set width(v) { this._size.x = v; } get height() { return this._size.y } set height(v) { this._size.y = v; } private readonly _size: TPoint = { x: 0, y: 0 }; private _parent?: Transform; public get parent() { return this._parent; } private readonly _children: Transform[] = []; public get children() { return this._children.values() } [Symbol.iterator]() { return this._children.values(); } constructor(pos?: Point | null) { super(); if (pos) { this._position.set(pos.x, pos.y); } } init() { } /** * Find all children with component type. * @param {*} cls * @param results - Optional array to place results in. */ findInChildren<T extends Component>(cls: Constructor<T>, results: Array<T> = []) { for (let i = this._children.length - 1; i >= 0; i--) { const comp = this._children[i].get(cls); if (comp) { results.push(comp); } } return results; } /** * Find components recursively in all children. * This is an expensive operation. * @param cls */ findRecursive<T extends Component>(cls: Constructor<T>, results: Array<T> = []) { for (let i = this._children.length - 1; i >= 0; i--) { const child = this._children[i]; const comp = child.get(cls); if (comp) { results.push(comp); } child.findRecursive(cls, results); } return results; } /** * * @param {number} x * @param {number} y */ translate(x: number, y: number) { this._position.x += x; this._position.y += y; } addChild(t: Transform) { if (t === this) { console.warn(`Attempt to set self as parent failed.`); } else if (t._parent != this) { const oldParent = t._parent; t._parent = this; oldParent?.removeChild(t); this._children.push(t); this.actor!.emit(EngineEvent.ChildAdded, t); } } /** * * @param t - Child transform to remove. * The child will be added to the root actor's children. * A transform cannot be removed from root. * To do this, add it to another transform's children instead. * @returns */ removeChild(t: Transform) { const ind = this._children.indexOf(t); if (ind >= 0) { quickSplice(this._children, ind); } this.actor?.emit(EngineEvent.ChildRemoved, t); if (t._parent == this) { t._parent = undefined; } } }