UNPKG

onsight

Version:

Interactive, easy to use JavaScript game framework.

184 lines (142 loc) 4.88 kB
import { WORLD_TYPES, } from '../../constants.js'; import { Entity } from './Entity.js'; import { Thing } from '../Thing.js'; import { Vector2 } from '../../math/Vector2.js'; class World extends Entity { constructor(type = WORLD_TYPES.WORLD_2D, name = 'World 1') { super(name); // Check if (Object.values(WORLD_TYPES).indexOf(type) === -1) { console.warn(`World: Invalid world type '${type}', using 'World2D`); type = WORLD_TYPES.WORLD_2D; } // Prototype this.isWorld = true; this.type = type; // Properties, Stage this.activeStageUUID = null; // Properties, Gameplay this.loadPosition = new Vector2(); this.loadDistance = 0; // Properties, Object2D this.pointerEvents = false; this.draggable = false; this.focusable = false; this.selectable = false; } componentFamily() { return [ 'World', this.type ]; } /******************** CHILDREN */ activeStage() { const stage = this.getStageByUUID(this.activeStageUUID); return stage ?? this; } setActiveStage(stage) { this.activeStageUUID = null; if (stage && stage.isEntity && this.getStageByUUID(stage.uuid)) { this.activeStageUUID = stage.uuid; } return this; } addEntity(...entities) { super.addEntity(...entities); if (!this.activeStageUUID) { const stages = this.getStages(); if (stages.length > 0) this.setActiveStage(stages[0]); } return this; } getEntities(includeStages = true) { const filteredChildren = []; for (const child of super.getEntities()) { if (!includeStages && child.isStage) continue; filteredChildren.push(child); } return filteredChildren; } getFirstStage() { const stages = this.getStages(); if (stages.length > 0) return stages[0]; } getStages() { const filteredChildren = []; for (const child of super.getEntities()) { if (child.isStage) filteredChildren.push(child); } return filteredChildren; } getStageByName(name) { const stage = this.getEntityByProperty('name', name); if (stage && stage.isStage) return stage; } getStageByUUID(uuid) { const stage = this.getEntityByProperty('uuid', uuid); if (stage && stage.isStage) return stage; } getStageByProperty(property, value) { for (const stage of this.getStages()) { if (stage[property] === value) return stage; } } /** Return 'true' in callback to stop further recursion */ traverseStages(callback, recursive = true) { const cancel = (typeof callback === 'function') ? callback(this) : false; if (cancel) return; for (const stage of this.getStages()) { stage.traverse(callback, recursive); } } /******************** COPY */ copy(source, recursive = true) { super.copy(source, recursive); // Type this.type = source.type; // Node this.position.copy(source.position); // Stage const stageIndex = source.getStages().indexOf(source.activeStage()); this.activeStageUUID = (stageIndex !== -1) ? this.getStages()[stageIndex].uuid : null; // Gameplay this.loadPosition.copy(source.loadPosition); this.loadDistance = source.loadDistance; return this; } /******************** DISPOSE */ dispose() { super.dispose(); } /******************** JSON */ toJSON(recursive = true) { const data = super.toJSON(recursive); // Type data.type = this.type; // Node data.position = JSON.stringify(this.position.toArray()); // Stage data.activeStageUUID = this.activeStageUUID; // Gameplay data.loadPosition = JSON.stringify(this.loadPosition.toArray()); data.loadDistance = this.loadDistance; return data; } fromJSON(data) { super.fromJSON(data); // Type if (data.type !== undefined) this.type = data.type; // Node if (data.position !== undefined) this.position.copy(JSON.parse(data.position)); // Stage if (data.activeStageUUID !== undefined) this.activeStageUUID = data.activeStageUUID; // Gameplay if (data.loadPosition !== undefined) this.loadPosition.copy(JSON.parse(data.loadPosition)); if (data.loadDistance !== undefined) this.loadDistance = data.loadDistance; return this; } } Thing.register('World2D', World); Thing.register('World3D', World); Thing.register('WorldUI', World); export { World };