我正在尝试设计一个简单的游戏引擎,以达到娱乐和教育目的。我有一个Game
协议代表我的游戏,有一个Entity
协议代表一个实体(例如玩家或对手)。最后,我有一个EntityComponent
协议,该协议的实现更新了Entity
。在Swift中看起来像这样:
protocol Game {
var entities: [Entity] { get }
}
protocol Entity {
var components: [EntityComponent] { get }
}
protocol EntityComponent {
func update(_ entity: Entity, deltaTime seconds: TimeInterval)
}
我希望使用它们更新的实体来概括我的实体组件。在Swift中,我可以使用associatedtype
:
protocol EntityComponent {
associatedtype EntityType: Entity
func update(_ entity: EntityType, deltaTime seconds: TimeInterval)
}
但是,这会为Entity
协议产生一个编译错误:
protocol Entity {
var components: [EntityComponent] { get } // ERROR!
}
协议“ EntityComponent”仅具有通用或相关类型要求,因此只能用作通用约束
可以通过为EntityComponent
协议定义类型擦除并更新Entity
来解决此问题:
protocol Entity {
var components: [AnyEntityComponent<Self>] { get }
}
final class AnyEntityComponent<EntityType: Entity>: EntityComponent {
init<T: EntityComponent>(_ component: T) where T.EntityType == EntityType {
self.update = component.update
}
func update(_ entity: EntityType, deltaTime seconds: TimeInterval) {
update(entity, seconds)
}
private let update: (EntityType, TimeInterval) -> Void
}
不幸的是,Entity
协议中的更改产生了另一个问题。这次使用Game
协议:
protocol Game {
var entities: [Entity] { get } // ERROR!
}
协议“实体”只能用作通用约束,因为它具有“自我”或关联的类型要求
我不确定如何解决此问题,因为我无法通过定义类型擦除来解决(例如EntityComponent
)。
我将不胜感激!
答案 0 :(得分:0)
删除相关的类型要求并改用泛型可能会有所帮助:
protocol EntityComponent {
func update<T: Entity>(_ entity: T, deltaTime seconds: TimeInterval)
}