GKEntity 和 GKComponent
實體表示遊戲的物件,如玩家形象或敵人形象。由於這個物體在沒有手臂和腿的情況下做得不多,我們可以為此新增元件。要建立這個系統,apple 有 GKEntity
和 GKComponent
類。
讓我們假設我們在以下章節中有以下內容:
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
}
}
除此之外,還可以覆蓋方法 didAddToEntity
和 willRemoveFromEntity
,以通知其他元件有關它的刪除或新增。
要操作元件內部的其他元件,可以獲得新增元件的 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
並在所有系統上呼叫更新。