UNPKG

@woosh/meep-engine

Version:

Pure JavaScript game engine. Fully featured and production ready.

158 lines (135 loc) 3.71 kB
import { assert } from "../../../../core/assert.js"; import { RepeatBehavior } from "../decorator/RepeatBehavior.js"; import { ActionBehavior } from "../primitive/ActionBehavior.js"; import { ClockChannelType } from "./ClockChannelType.js"; /** * ECS wrapper around a {@link Behavior} tree. Allows complex scripting behavior, including parallelization. * Requires {@link BehaviorSystem} to be registered on {@link EntityManager}. * * @example * new Entity() * .add(BehaviorComponent.from( * SequenceBehavior.from([ * DelayBehavior.from(10), * DieBehavior.create(), * ]) * )) * .build(ecd); // entity will self-destruct after 10 seconds * * @author Alex Goldring * @copyright Company Named Limited (c) 2025 */ export class BehaviorComponent { /** * What clock should be used for ticking associated behavior. * Some behaviors need to run at the world's simulated time, while others will need to be executed in real-world time. * @type {ClockChannelType|number} */ clock = ClockChannelType.Simulation; /** * * @type {number} */ flags = 0; /** * Associated behavior tree * @type {Behavior|null} * @private */ __behavior = null; /** * * @param {number|BehaviorComponentFlag} flag * @returns {void} */ setFlag(flag) { this.flags |= flag; } /** * * @param {number|BehaviorComponentFlag} flag * @returns {void} */ clearFlag(flag) { this.flags &= ~flag; } /** * * @param {number|BehaviorComponentFlag} flag * @param {boolean} value */ writeFlag(flag, value) { if (value) { this.setFlag(flag); } else { this.clearFlag(flag); } } /** * * @param {number|BehaviorComponentFlag} flag * @returns {boolean} */ getFlag(flag) { return (this.flags & flag) === flag; } /** * * @returns {Behavior|null} */ get behavior() { return this.__behavior; } /** * Note that swapping behaviors during simulation may have unintended consequences * @param {Behavior} v */ set behavior(v) { this.__behavior = v; } /** * Executes input function every update cycle. * Will run forever, or until function throws. * @param {function(time_delta_seconds:number)} action function to loop over * @param {*} [thisArg] * @returns {BehaviorComponent} */ static loop(action, thisArg) { return BehaviorComponent.from( RepeatBehavior.from( new ActionBehavior(action, thisArg) ) ); } /** * * @param {Behavior} b * @returns {BehaviorComponent} */ static from(b) { assert.defined(b, 'behavior'); assert.notNull(b, 'behavior'); assert.equal(b.isBehavior, true, 'b.isBehavior !== true'); const result = new BehaviorComponent(); result.__behavior = b; return result; } } /** * @deprecated use {@link BehaviorComponent.from} instead */ BehaviorComponent.fromOne = BehaviorComponent.from; /** * @deprecated use {@link BehaviorComponent.loop} instead */ BehaviorComponent.looping_function = BehaviorComponent.loop; /** * @readonly * @type {boolean} */ BehaviorComponent.serializable = true; /** * @readonly * @type {string} */ BehaviorComponent.typeName = 'BehaviorComponent';