Я использую наборы GamePlay Entity - Система компонентов для 2D-игры. Каждая сущность имеет набор GKComponents — spriteComponent, physicComponent и т. д., а также GKComponent (ChaseScrollMovement.swift), который берет спрайт-компонент Entities и перемещает его по экрану.
Добавление компонента ChaseScrollMovment к вражескому объекту
addComponent(physicsCompnment);
scrollerComponent = ChaseScrollComponent(entity: self, isEnemey : true);
addComponent(scrollerComponent);
Проблема в том, что когда я удаляю EnemyEnity из GameScence (при контакте с 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;
....EnemeyEnitiy удаляется из GameScene, затем метод обновления GameScene вызывает метод обновления компонента....
Компоненты в 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 не может найти spriteCompnment EnemyEntity, поскольку он удаляется из сцены, и здесь возникает исключение....
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 (их много в сцене) удаляется из сцены и позволяет компонентам успешно обновляться в течение жизненного цикла GameScene .
Заранее спасибо
Обновление: Попытался удалить компоненты из системы, чтобы метод 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:), которую вы можете попробовать вызов, когда вы удаляете объект, который должен удалить ссылку на компонент из системы. - person Mark Brownsword   schedule 27.01.2017nil
. - person Mark Brownsword   schedule 27.01.2017