An entity represents an object of a game like a player figure or an enemy figure. Since this object does not do much without arms and legs we can add the components to this. To create this system apple has the GKEntity and GKComponent classes.

Lets assume we have the following classe for the following chapters:

class Player: GKEntity{}
class PlayerSpriteComponent: GKComponent {}

GKEntity

An entity is a collection of components and offers several functions to add, remove and interact with components of it.

While we could just use the GKEntity it is common to Subclass it for a specific type of game entity.

It is important that it is only possible to add a component of a class once. In case you add a second component of the same class it will override the first exsisting component inside of the GKEntity

let otherComponent = PlayerSpriteComponent()
var player = Player()
player.addComponent(PlayerSpriteComponent())
player.addComponent(otherComponent)
print(player.components.count) //will print 1
print(player.components[0] === otherComponent) // will print true

You may ask why. The reason for this is the methods called component(for: T.Type) which returns the component of a specific type of the entity.

let component = player.component(ofType: PlayerSpriteComponent.self)

In addition to the components-methods it has an update method which is used to delegate the delta time or current time of the game logic to it’s components.

var player = Player()
player.addComponent(PlayerSpriteComponent())
player.update(deltaTime: 1.0) // will call the update method of the PlayerSpriteComponent added to it

GKComponent

A component represents something of an entity for example the visual component or the logic component.

If an the update method of an entity is called it will delegate this to all of it’s components. Overriding this method is used to manipulate an Entity.

class PlayerSpriteComponent: GKComponent {
    override func update(deltaTime seconds: TimeInterval) {
        //move the sprite depending on the update time
    }
}

In addition to this it is possible to override the method didAddToEntity and willRemoveFromEntity to inform other components about it’s removal or add.

To manipulate a other component inside of a component it is possible to get the GKEntity which the component is added to.

override func update(deltaTime seconds: TimeInterval) {
    let controller = self.entity?.component(ofType: PlayerControlComponent.self)
    //call methods on the controller
}

While this is possible it is not a common pattern since it wires the two components together.