iOS GKEntity et GKComponent


Exemple

Une entité représente un objet d'un jeu comme une figure de joueur ou une figure ennemie. Puisque cet objet ne fait pas grand chose sans les bras et les jambes, nous pouvons y ajouter les composants. Pour créer ce système, Apple a les classes GKEntity et GKComponent .

Supposons que nous avons la classe suivante pour les chapitres suivants:

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

GKEntity

Une entité est un ensemble de composants et offre plusieurs fonctions pour ajouter, supprimer et interagir avec ses composants.

Bien que nous puissions simplement utiliser GKEntity, il est courant de le sous-classer pour un type spécifique d'entité de jeu.

Il est important de n’ajouter qu’un composant d’une classe. Si vous ajoutez un second composant de la même classe, il remplacera le premier composant existant dans 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

Vous pouvez demander pourquoi. La raison en est les méthodes appelées component(for: T.Type) qui renvoie le composant d'un type spécifique de l'entité.

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

En plus des méthodes de composants, il dispose d'une méthode de update qui permet de déléguer le delta time ou l'heure actuelle de la logique de jeu à ses composants.

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

GKComponent

Un composant représente quelque chose d'une entité, par exemple le composant visuel ou le composant logique.

Si une méthode de mise à jour d'une entité est appelée, elle la déléguera à tous ses composants. La substitution de cette méthode est utilisée pour manipuler une entité.

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

En plus de cela, il est possible de remplacer la méthode didAddToEntity et willRemoveFromEntity pour informer les autres composants de sa suppression ou de son ajout.

Pour manipuler un autre composant à l'intérieur d'un composant, il est possible d'obtenir le GKEntity auquel le composant est ajouté.

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

Bien que cela soit possible, ce n’est pas un modèle courant car il relie les deux composants.

GKComponentSystem

Alors que nous venons de parler de l'utilisation du mécanisme de GKEntity de mise à jour de GKEntity pour mettre à jour les GKComponents il existe une autre façon de mettre à jour GKComponents appelée GKComponentSystem .

Il est utilisé dans le cas où il est nécessaire que tous les composants d'un type spécifique doivent être mis à jour en une fois.

Un GKComponentSystem est créé pour un type de composant spécifique.

let system = GKComponentSystem(componentClass: PlayerSpriteComponent.self)

Pour ajouter un composant, vous pouvez utiliser la méthode add:

system.addComponent(PlayerSpriteComponent())

Mais une manière plus courante est de passer l'entité créée avec ses composants au GKComponentSystem et elle trouvera un composant correspondant à l'intérieur de l'entité.

system.addComponent(foundIn: player)

Pour mettre à jour tous les composants d'un type spécifique, appelez la mise à jour:

system.update(deltaTime: delta)

Si vous souhaitez utiliser GKComponentSystem au lieu d'un mécanisme de mise à jour basé sur une entité, vous devez avoir un GKComponentSystem pour chaque composant et appeler la mise à jour sur tous les systèmes.