我正在尝试设计一个用于娱乐和教育目的的简单游戏引擎。我有一个代表我的游戏的 Game
协议(protocol)和代表一个实体(比如玩家或对手)的 Entity
协议(protocol)。最后,我有一个 EntityComponent
协议(protocol),它的实现更新了一个 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)的编译错误:
protocol Entity {
var components: [EntityComponent] { get } // ERROR!
}
Protocol 'EntityComponent' can only be used as a generic constraint because it has Self or associated type requirements
这个问题可以通过为 EntityComponent
协议(protocol)定义类型删除并像这样更新 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
协议(protocol)中的更改会产生另一个问题。这次在 Game
协议(protocol)中:
protocol Game {
var entities: [Entity] { get } // ERROR!
}
Protocol 'Entity' can only be used as a generic constraint because it has Self or associated type requirements
我不确定如何解决这个问题,因为我无法通过定义类型删除来解决这个问题(如 EntityComponent
的情况)。
我将不胜感激任何提示和想法!
最佳答案
它可能有助于删除关联的类型要求并改用泛型:
protocol EntityComponent {
func update<T: Entity>(_ entity: T, deltaTime seconds: TimeInterval)
}
关于具有 self 类型要求的协议(protocol)的 Swift 类型删除,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55736034/