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.