GKEntity 和 GKComponent

实体表示游戏的对象,如玩家形象或敌人形象。由于这个物体在没有手臂和腿的情况下做得不多,我们可以为此添加组件。要创建这个系统,apple 有 GKEntityGKComponent 类。

让我们假设我们在以下章节中有以下内容:

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

GKEntity

实体是组件的集合,并提供若干功能来添加,删除和与组件相互作用。

虽然我们可以使用 GKEntity,但通常会将其子类化为特定类型的游戏实体。

重要的是,只能添加一次类的组件。如果你添加同一个类的第二个组件,它将覆盖 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

你可能会问为什么。其原因是名为 component(for: T.Type) 的方法,它返回特定类型实体的组件。

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

除了组件方法之外,它还有一个 update 方法,用于将游戏逻辑的增量时间或当前时间委托给它的组件。

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

GKComponent

组件表示实体的某些东西,例如可视组件或逻辑组件。

如果调用实体的更新方法,它将委托给它的所有组件。覆盖此方法用于操作实体。

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

除此之外,还可以覆盖方法 didAddToEntitywillRemoveFromEntity,以通知其他组件有关它的删除或添加。

要操作组件内部的其他组件,可以获得添加组件的 GKEntity。

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

虽然这是可能的,但它不是常见的模式,因为它将两个组件连接在一起。

GKComponentSystem

虽然我们刚刚谈到使用 GKEntity 的更新委托机制来更新 GKComponents,但是有一种不同的方式来更新 GKComponents,这被称为 GKComponentSystem

如果需要特定类型的所有组件需要一次更新,则使用它。

为特定类型的组件创建 GKComponentSystem

let system = GKComponentSystem(componentClass: PlayerSpriteComponent.self)

要添加组件,你可以使用 add 方法:

system.addComponent(PlayerSpriteComponent())

但更常见的方法是将创建的实体与其组件一起传递给 GKComponentSystem,它将在实体内部找到匹配的组件。

system.addComponent(foundIn: player)

要更新特定类型的所有组件,请调用更新:

system.update(deltaTime: delta)

如果你想使用 GKComponentSystem 而不是基于实体的更新机制,则必须为每个组件提供 GKComponentSystem 并在所有系统上调用更新。