【发布时间】:2017-01-26 22:01:30
【问题描述】:
我正在使用 GamePlay 套件实体 - 用于 2d 游戏的组件系统。 每个实体都有一系列 GKComponents - spriteComponent、physicComponent 等和一个 GKComponent (ChaseScrollMovement.swift),它接收一个 Entities spriteComponent 并将其在屏幕上移动。
向 Enemy Enity 添加 ChaseScrollMovment 组件
addComponent(physicsCompnment);
scrollerComponent = ChaseScrollComponent(entity: self, isEnemey : true);
addComponent(scrollerComponent);
问题是当我从 GameScence 中移除 EnemyEnity 时(与 WeaponEnity 进行接触时):
Class ThrowWeaponEnity.....didBginContact...
case "enemyEntity":
if let spriteComponentEnemy = entity.componentForClass(SpriteComponent.self){
let pos = spriteComponentEnemy.node.position;
//Remove enemy sprote and its entiy
spriteComponentEnemy.node.parent?.runAction(SKAction.playSoundFileNamed("110548__noisehag__comp-cover-02.wav", waitForCompletion: false));
spriteComponentEnemy.node.removeAllActions();
spriteComponentEnemy.node.removeFromParent();
//Remove the entire entity
entity.removeComponentForClass(SpriteComponent.self);
emitterExplosion(pos);
}
break;
....从 GameScene 中移除 EnemeyEnitiy,GameScene 更新方法然后调用 Component 更新方法....
GameScene 中的组件
lazy var componentSystems: [GKComponentSystem] = {
let parallaxSystem = GKComponentSystem(componentClass: ParallaxComponent.self)
let animationSystem = GKComponentSystem(componentClass: AnimationComponent.self)
let scrollerSystem = GKComponentSystem(componentClass: ChaseScrollComponent.self)
return [animationSystem, parallaxSystem, scrollerSystem]
}()
let scrollerSystem = FullControlComponentSystem(componentClass: FullControlComponent.self).......
//MARK: Life Cycle
override func update(currentTime: CFTimeInterval) {
if !pauseLoop {........
// Update Components
for componentSystem in componentSystems {
componentSystem.updateWithDeltaTime(deltaTime)
}
.....因此,ChaseScroll 组件无法找到 EnemyEntity 的 spriteCompnment,因为它已从场景中移除,并在此处引发异常......
class ChaseScrollComponent: GKComponent {
var spriteComponent: SpriteComponent {
//Called after Init() and during GaemplayMode.updat / componments.udate
guard let spriteComponent = entity?.componentForClass(SpriteComponent.self)
else{
fatalError("SpriteCompnemnet Missing");
}
print("SpriteCompnemnt for CHaseScroll GKConponent : \(spriteComponent.node.name)")
return spriteComponent;
}
我是 Enity-Compnent 系统的新手,所以我想知道当从场景中移除单个 EnemyEntity(场景中有很多)并允许组件在游戏场景生命周期。
提前致谢
更新: 尝试从系统中删除组件,以便在游戏场景更新中不会调用组件 upDate 方法:
//在我们的游戏场景中
func removeEntity(entity : GKEntity){
print("Enity hashValue and \(entity.hash)description: \(entities.count)");
if entities.contains(entity){
//Remove the entities components
let entiyRemoved = entities.remove(entity);
entity.removeComponentForClass(PhysicsComponent.self);
entity.removeComponentForClass(ChaseScrollComponent.self);
}
//Remove entity from array of enities
entities.remove(entity); print(entities.count);
for componentsytem in self.componentSystems{
//Remove componment is from the system not the entity, so if removed the component update will not be called
componentsytem.removeComponentWithEntity(entity); }
}
但是应该删除的组件仍然调用它的更新,在此更新中,实体 spriteComponent 的初始化按预期失败,因为我们已从实体中删除了组件(并试图从系统中删除!):
var spriteComponent: SpriteComponent {
guard let spriteComponent = entity?.componentForClass(SpriteComponent.self)
else{
fatalError("SpriteCompnemnet Missing");
}
print("SpriteCompnemnt for CHaseScroll GKConponent : \(spriteComponent.node.name)")
return spriteComponent;
}
因此似乎仍然无法从系统中删除组件,因为它的更新仍被调用或无法从系统中删除实体。
【问题讨论】:
-
GKComponentSystem有一个 removeComponent(foundIn:) 函数,您可以在删除实体时尝试调用该函数,这应该会从系统中删除组件引用。 -
谢谢,但是当实体本身被移除时,实体组件是否应该从场景中移除?
-
我会明确删除它,尽管您没有在代码中显示如何将组件与系统关联。
-
在类 ThrowWeaponEntity ..... entityRemoveComponentForClass .....但我开始怀疑这是否实际上是在删除实体,因为有对 CKComponents remianjng 的引用
-
是的,您移除了节点,但留下了实体。
标签: sprite-kit swift2 gameplay-kit