UNPKG

seed-engine

Version:

A Lightweight 2D game engine using WebGL2. The engine is designed on the focus of creating a bridge between creating and publishing games to the Seed Network as modules.

208 lines (190 loc) 6.97 kB
import Updateable from '../base/Updateable'; import Component from '../component/Component'; import Transform from '../component/Transform'; /** * Baseclass GameObject which derives from Updateable. * * Do not derive this class directly! GameObjects are not managed until they are assigned to a manager. * Instead, derive SceneObject or PersistentObject to create objects that exist the scope of a scene, or the scope of the game. * * All objects that should exist in the game screen should derive this. */ export default class GameObject extends Updateable { /** * Default position, size and rotation of the Object. * * @param {Point} position A point of creation in the world. * @param {Point} size A point representing scale of the object. * @param {number} rotation A number representing angular rotation (in degrees). */ constructor(position = new Point(0, 0, 0), size = new Point(32, 32, 1), rotation = 0) { super(); this.className = 'GameObject'; this.components = {}; this.addComponent(new Transform(position, size, rotation)); this.transform = this.getComponent("Transform"); } /** * Adds a component to this game object, and keeps reference to it. * GameObjects will handle their components as they are added to the object. * * @param {Component} component The component assigned to this object. */ addComponent(component) { if (this.components[component.className] == null) { this.components[component.className] = []; } if (component.isUnique && this.components[component.className].length > 0) { throw 'There is already a unique component of type ' + component.className + ' on this GameObject!'; return false; } this.components[component.className].push(component); component.gameObject = this; component.onAddComponent(); return true; } /** * Removes a single component from this GameObject by ID. * * @param {number} componentID Id of the component to remove. */ removeComponent(componentName, componentID) { if (this.components[componentName] == null) return false; for (let i = 0; i < this.components[componentName].length; i++) { if (this.components[componentName][i].id === componentID) { let comp = this.components[componentName][i]; this.components[componentName].splice(i, 1); comp.end(); return true; } } return false; } /** * Removes all Components of the named type. * * @param {string} componentName The name of the components to clear. */ removeComponents(componentName) { if (this.components[componentName] == null) return false; for (let i = this.components[componentName].length - 1; i >= 0; i--) { let comp = this.components[componentName][i]; this.components[componentName].splice(i, 1); comp.end(); } return true; } /** * Removes all components except for the Transform component. */ removeAllComponents() { let compTypes = Object.keys(this.components); for (let i = 0; i < compTypes.length; i++) { let thisCompType = compTypes[i]; if (thisCompType === 'Transform') continue; for (let ii = 0; ii < this.components[thisCompType].length; ii++) { this.components[thisCompType][ii].end(); } this.components[thisCompType] = []; } return true; } /** * Returns a boolean on if there is a component of type {componentName}. * * @param {string} componentName Name of the component type to search for. * * @returns {boolean} true if there is at least one component of this type. */ hasComponent(componentName) { if (this.components[componentName] == null) { return false; } return this.components[componentName].length > 0; } /** * Returns a component of type {componentName}. The second parameter can determine which * Component of that type to return if there are more than 1. * * @param {string} componentName Name of the component type to return. * @param {*} index Index of the component to get. Defaults to first component. */ getComponent(componentName, index = 0) { if (this.components[componentName] == null) { return null; } return this.components[componentName][index]; } /** * Updates all components on this GameObject. */ updateComponents() { let compTypes = Object.keys(this.components); for (let i = 0; i < compTypes.length; i++) { let thisCompType = compTypes[i]; for (let ii = 0; ii < this.components[thisCompType].length; ii++) { this.components[thisCompType][ii].update(); } } } onPause() { let compTypes = Object.keys(this.components); for (let i = 0; i < compTypes.length; i++) { let thisCompType = compTypes[i]; for (let ii = 0; ii < this.components[thisCompType].length; ii++) { this.components[thisCompType][ii].pause(); } } } onUnpause() { let compTypes = Object.keys(this.components); for (let i = 0; i < compTypes.length; i++) { let thisCompType = compTypes[i]; for (let ii = 0; ii < this.components[thisCompType].length; ii++) { this.components[thisCompType][ii].unpause(); } } } /** * Rewritten update() functions which is originally defined in Updateable. * The GameObject adds a pre and post update function, and respective overrideable callbacks * (onPreUpdate and onPostUpdate). */ update() { if (this.hasPaused) return; if (!this.hasStarted) { this.start(); return; } this.preUpdate(); this.onUpdate(); this.updateComponents(); this.postUpdate(); } /** * Called by the GameObject before an update to do default calls for preUpdating. Afterwards it * calls the overrideable function, onPreUpdate. */ preUpdate() { this.onPreUpdate(); } /** * Called by the GameObject after an update to do default calls for postUpdating. Afterwards it * calls the overrideable function, onPostUpdate. */ postUpdate() { this.onPostUpdate(); } /** * Override for Pre Update functionality. */ onPreUpdate() {} /** * Override for Post Update functionality. */ onPostUpdate() {} }