Home Reference Source Repository

js/GameplayKit/GKEntity.js

  1. 'use strict'
  2.  
  3. import NSObject from '../ObjectiveC/NSObject'
  4. import GKComponent from './GKComponent'
  5. import _InstanceOf from '../util/_InstanceOf'
  6.  
  7. /**
  8. * An object relevant to gameplay, with functionality entirely provided by a collection of component objects.
  9. * @access public
  10. * @extends {NSObject}
  11. * @see https://developer.apple.com/documentation/gameplaykit/gkentity
  12. */
  13. export default class GKEntity extends NSObject {
  14.  
  15. // Creating an Entity
  16.  
  17. /**
  18. * Initializes a new entity object.
  19. * @access public
  20. * @constructor
  21. * @desc If you create a GKEntity subclass and define any additional initializers, you must delegate to this initializer. You do not need to subclass GKEntity to use Entity-Component architecture—generally, you should create a custom entity class only when you need a place to store state or resources that are shared by multiple components.
  22. * @see https://developer.apple.com/documentation/gameplaykit/gkentity/1501143-init
  23. */
  24. constructor() {
  25. super()
  26.  
  27. // Managing an Entity’s List of Components
  28.  
  29. this._components = []
  30. }
  31.  
  32. // Managing an Entity’s List of Components
  33.  
  34. /**
  35. * Adds a component to the entity.
  36. * @access public
  37. * @param {GKComponent} component - An instance of a GKComponent subclass.
  38. * @returns {void}
  39. * @desc You create components by subclassing GKEntity to implement reusable behavior. Then, use this method to incorporate the behavior of a component class into that entity. An entity’s components list never has more than one instance of any component class—if the entity already contains a component of the same class as the component parameter, calling this method will replace that component.
  40. * @see https://developer.apple.com/documentation/gameplaykit/gkentity/1501312-addcomponent
  41. */
  42. addComponent(component) {
  43. if(this._components.indexOf(component) < 0){
  44. this._components.push(component)
  45. component._entity = this
  46. component.didAddToEntity()
  47. }
  48. }
  49.  
  50. /**
  51. * The entity’s list of components.
  52. * @type {GKComponent[]}
  53. * @desc
  54. * @see https://developer.apple.com/documentation/gameplaykit/gkentity/1501182-components
  55. */
  56. get components() {
  57. return this._components.slice()
  58. }
  59.  
  60. // Performing Periodic Updates
  61.  
  62. /**
  63. * Performs periodic updates for each of the entity’s components.
  64. * @access public
  65. * @param {number} seconds - The time step to use for any time-dependent actions performed by this method (typically, the elapsed time since the previous call to this method).
  66. * @returns {void}
  67. * @desc At runtime, an entity/component-based game needs to dispatch periodic logic—from an update/render loop method such as update(_:) (SpriteKit) or renderer(_:updateAtTime:) (SceneKit), or a CADisplayLink (iOS) or CVDisplayLink (macOS) timer in a custom rendering engine—to each of its components, so that each can perform component-specific update logic.The GKEntity update(deltaTime:) method is one of the two options GameplayKit provides for dispatching updates—this option is easy to implement in games with small numbers of entities and components. Call this method for each entity in your game, and each entity will in turn call the update(deltaTime:) method for each of its components.The other option is to dispatch updates per-component, rather than per-entity, using a GKComponentSystem object. Using a component system allows you to update all components of a specific component class in a deterministic order, without needing to traverse your game’s object graph and update each entity.NoteIf a component owned by an entity is a member of a component system, calling the entity’s update(deltaTime:) method will not update that component.
  68. * @see https://developer.apple.com/documentation/gameplaykit/gkentity/1501228-update
  69. */
  70. updateDeltaTime(seconds) {
  71. }
  72.  
  73. // Instance Methods
  74.  
  75. /**
  76. *
  77. * @access public
  78. * @param {ComponentType.Type} componentClass -
  79. * @returns {GKComponent} -
  80. * @see https://developer.apple.com/documentation/gameplaykit/gkentity/2300466-component
  81. */
  82. componentOfType(componentClass) {
  83. return this._components.find((component) => _InstanceOf(component, componentClass))
  84. }
  85.  
  86. /**
  87. *
  88. * @access public
  89. * @param {ComponentType.Type} componentClass -
  90. * @returns {void}
  91. * @see https://developer.apple.com/documentation/gameplaykit/gkentity/2300467-removecomponent
  92. */
  93. removeComponentOfType(componentClass) {
  94. for(const component of this._components){
  95. if(_InstanceOf(component, componentClass)){
  96. component.willRemoveFromEntity()
  97.  
  98. const index = this._components.indexOf(component)
  99. if(index >= 0){
  100. this._components.splice(index)
  101. component._entity = null
  102. }
  103. }
  104. }
  105. }
  106. }