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 並在所有系統上呼叫更新。