我使用Spritekit潜入GameplayKit并从我收集的内容中继承GKEntity
,然后开始向该实体添加GKComponents
。该实体或多或少只是一个充满某些功能的组件包。
我感到困惑的部分是组件之间的通信。你如何让他们脱钩。例如,假设我有一个HealthComponent
类,我将该组件添加到PlayerEntity
和EnemyEntity
。我还有HealthBarComponent
,但我只想在播放器上方显示健康栏。当玩家受到伤害时,需要在HealthBarComponent
中更新该信息。
那么该信息应该如何发送?我看到文档中有一个名为GKComponentSystem
的类。我不是100%应该如何使用它。
另一个问题是......当玩家的生命值达到零时,他应该在敌人应该死的时候重生。当玩家用完生命时,游戏结束。
敌人和玩家的卫生系统大致相同,但死亡事件对每个人来说都是完全不同的。我没有遵循如何使用组件系统,同时保持每个实体的独特行为。
一些伪代码会很棒
答案 0 :(得分:5)
看起来这个框架与我见过的其他框架的工作方式略有不同,因为系统只能处理单一类型的组件,而不能处理组件类型为 groups 的实体。
在GamePlay-Kit框架中,您可以手动循环并更新实体(然后更新每个实体组件)或创建一个继承自GKComponentSystem的类。然后,当您更新系统时,它会更新所有组件you have added to it,只要它们的类类型与您initialized the system with
的类型相匹配要处理您的健康栏问题,我会说HealthBarComponent
,在更新过程中,从其所有者实体中检索HealthComponent
,读取健康值&每帧渲染自己。但您只有add HealthBarComponent
到您的玩家实体。
您可以从组件中检索所有者实体,反之亦然(请参阅GKComponent.entity& GKEntity.components),以便您可以像这样更新健康栏:
/*Note: I'm not an ios developer, this is pseudocode*/
HealthBarComponent.update(){
int healthValue = self.entity.components.get(HealthComponent).value;
//Now render your health bar accordingly or hold onto this for later
}
为了处理玩家死亡问题,我认为你最好的选择是拥有两种不同类型的健康组件(PlayerHealth& EnemyHealth)和两个不同的相应系统。那或者有一个健康组件,但有两个独立的'死亡'组件。是的,这似乎是多余的,但我很难想到在这个框架内有更好的方法。根据我的经验,你要么花时间担心保持一切完全脱离和可重复使用,要么建立一个游戏:)
答案 1 :(得分:3)
组件可以通过self.entity
属性访问其实体。从那里,您可以查询其他组件以通过实体componentForClass
属性传递数据:
guard let moveComponent = entity?.componentForClass(MoveComponent.self) else {
fatalError("A MovementComponent's entity must have a MoveComponent")
}
iOS Games by Tutorials本书有一个很好的教程,涵盖了GameplayKit实体和组件。
答案 2 :(得分:0)
通知对于此类问题很好。根本就没有直接的对象耦合,如果一个以上的对象最终需要知道(例如,您的健康条组件,确定游戏结束的更高级别的游戏对象,甚至敌人/盟友AI在以下情况下的行为有所不同),这是非常可扩展的健康低下。)
您可以收到一个名为“ playerHealthChanged”的通知,并让您的健康栏组件和其他对象独立注册以响应该事件。 (您可能需要让HealthComponent实例知道是否应该发布此通知,因此仅玩家可以发布-也许可以在其实体上使用isKind(of :),或者仅具有一个bool字段来启用发布,将其设置为true播放器实例)。
我通常将所有通知名称定义放在一个模块中,以便任何类都可以访问它们:
let kPlayerHealthChangedNotification = Notification.Name("playerHealthChanged")
这是组件发布通知的方式(如果需要,您可以传递self以外的其他对象):
NotificationCenter.default.post(name: kPlayerHealthChangedNotification, object:self)
然后,关心玩家健康状况变化的对象可以像在其初始代码中一样进行注册-创建处理程序函数,而不是将self添加为通知的观察者:
@objc func onPlayerHealthChanged(_ notification:Notification) {
// do whatever is needed; notification.object
// has the object from the post
}
// put this in a setup method - init or similar:
NotificationCenter.default.addObserver(self,
selector: #selector(onPlayerHealthChanged(_:)),
name: kPlayerHealthChangedNotification
object:nil)
以下是文档:https://developer.apple.com/documentation/foundation/notifications