SpriteKit iOS 7 Sknode не удаляется

Я разрабатываю игру для iOS 7, и она использует Spritekit.

Основным skspritenode является вертолет, и когда этот вертолет вступает в контакт с приемом бонуса сжатия, вертолет сжимается, чтобы упростить навигацию для пользователя. Вот код для сокращения вертолета, который работает как ожидалось (self относится к skspritenode вертолета):

SKAction *scaleHeli = [SKAction scaleBy:.70 duration:1];
SKAction *setPhysicsBody = [SKAction runBlock:^{
self.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:CGSizeMake(self.size.width, self.size.height)];
self.physicsBody.mass = 0.080944441;
self.physicsBody.restitution = 1.0f;
self.physicsBody.allowsRotation = FALSE;
self.physicsBody.categoryBitMask = APAColliderTypeShip;
self.physicsBody.collisionBitMask = APAColliderTypeCavePiece;
self.physicsBody.contactTestBitMask = APAColliderTypeCavePiece | APAColliderTypeBonusPickup;
}];

SKAction *seq = [SKAction sequence:@[scaleHeli, setPhysicsBody]];

[self runAction:seq];
_shrinkEnabled = true;

У меня есть таймер для бонуса сокращения, который длится в течение заранее определенного промежутка времени:

-(void)startShrinkTimer
{
    //Creating the timer for the shield
    _timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self    selector:@selector(countDownShrinkDuration) userInfo:Nil repeats:true];
    _timerSeconds = 15;
}

-(void)countDownShrinkDuration
{
    if(_timerSeconds > 0)
    {
        --_timerSeconds;
    }
    else if(_timerSeconds == 0)
    {
        [_sceneRef disableShrinkBonus];
        [_timer invalidate];
    }

    if(_timerSeconds < 5)
    {
        [_sceneRef shrinkWearingOut];
    }
}

Если таймер становится меньше 5 секунд, то вызывается функция shrinkWearingOut, которая добавляет метку к узлу, который исчезает и исчезает (self относится к skspritenode вертолета):

SKLabelNode *downLbl = [[SKLabelNode alloc] init];
downLbl.text = @"↓";
downLbl.fontColor = [UIColor whiteColor];
downLbl.fontSize = 9.0f;
downLbl.horizontalAlignmentMode = SKLabelHorizontalAlignmentModeLeft;
downLbl.position = CGPointMake(0,-30);
downLbl.zPosition = 5;

SKAction *fadeOut = [SKAction fadeOutWithDuration: .2];
SKAction *fadeIn = [SKAction fadeInWithDuration: .2];
SKAction *pulse = [SKAction sequence:@[fadeOut,fadeIn]];

SKAction *pulseForever = [SKAction repeatActionForever:pulse];

SKSpriteNode *wearingOut = [[SKSpriteNode alloc] init];
wearingOut.name = @"wearingOut";

[wearingOut addChild:downLbl];

[wearingOut runAction:pulseForever];

[self addChild:wearingOut];

Как только таймер достигает нуля, вызывается функция disableShrink, которая пытается удалить пульсирующий узел и масштабировать вертолет до его первоначального размера (self относится к skspritenode вертолета):

[[self childNodeWithName:@"wearingOut"] removeFromParent];

SKAction *scaleHeli = [SKAction scaleBy:1.3 duration:1];
SKAction *setPhysicsBody = [SKAction runBlock:^{
    self.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:CGSizeMake(self.size.width, self.size.height)];
    self.physicsBody.mass = 0.080944441;
    self.physicsBody.restitution = 0.0f;
    self.physicsBody.allowsRotation = FALSE;
    self.physicsBody.categoryBitMask = APAColliderTypeShip;
    self.physicsBody.collisionBitMask = APAColliderTypeCavePiece;
    self.physicsBody.contactTestBitMask = APAColliderTypeCavePiece | APAColliderTypeBonusPickup;

    _shrinkEnabled = false;
}];

SKAction *seq = [SKAction sequence:@[scaleHeli, setPhysicsBody]];

[self runAction:seq];

Проблема № 1: Эта строка кода: [[self childNodeWithName:@"wearOut"] removeFromParent]; на самом деле не удаляет пульсирующий узел из вертолетного узла, я установил здесь точку останова и проверил, что узел не равен нулю, но, тем не менее, он по-прежнему не удаляет узел. Очень расстраивает, так как я использовал одну и ту же строку кода с другим бонусным пикапом с другим именем, и он работает просто отлично. Единственное отличие состоит в том, что другой бонусный пикап использует skshapenode, так как оба они наследуют от sknode, поэтому они должны функционировать одинаково.

Проблема № 2: пульсирующий узел добавляется успешно, но пульсирует только пару раз, что я нахожу странным, потому что я использую точный набор skactions для другого бонуса и этот бонус импульсов, пока он не будет удален из вертолетного узла.

1 ответ

Замечания:

Вы не должны использовать NSTimer. Вместо этого используйте update: метод SKScene для выполнения синхронизированных действий и при необходимости перенаправления его на дочерние узлы, которые в этом нуждаются. Или используйте SKAction runBlock последовательность с waitForDuration, NSTimer может не работать синхронно с циклом обновления / рендеринга Sprite Kit, и он не прекратит запуск, если узел или сцена приостановлены.

Убедитесь, что у вас нет нескольких дочерних узлов с именем "wearOut". Похоже, вы могли добавить более одного. Использование NSTimer может на самом деле вызвать странное поведение, потому что Sprite Kit может задержать добавление / удаление узлов из сцены, и поэтому может возникнуть проблема с временем добавления / удаления узлов. Это дикое предположение, хотя.

Пульсирующая проблема может также указывать на множественные спрайты, возможно, они пульсируют асинхронно, поэтому они выглядят как не пульсирующие. Или попробуйте fadeAlphaTo: действия.

В общем, попробуйте использовать документированные инициализаторы. Там могут быть проблемы, если вы просто [[SKLabelNode alloc] init], Я столкнулся с некоторыми проблемами с [SKSpriteNode node] не рисовать, например, даже после установки текстуры. Вместо этого [SKLabelNode labelNodeWithFontNamed:@"Arial"] или любой из других назначенных инициализаторов. Обратитесь к ссылке на Sprite Kit Framework.

Другие вопросы по тегам