SpriteKit iOS 7 Sknode未被删除

时间:2014-03-20 19:34:32

标签: sprite-kit skspritenode sknode sklabelnode

我正在为iOS 7开发游戏,它使用Spritekit。

主要的skspritenode是一架直升机,当这架直升机与收缩奖励拾取器接触时,直升机缩小,使用户更容易导航。以下是缩小直升机工作的代码(自我指直升机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函数,这会向淡入和淡出的节点添加标签(自称为直升机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函数,该函数会尝试移除脉动节点并将直升机缩放到其原始大小(自称为直升机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:@&#34; wearingOut&#34;] removeFromParent]; 实际上并没有从直升机节点中移除脉动节点,我在这里设置了断点并验证了节点不是零,但它似乎仍然没有移除节点。非常令人沮丧,因为我使用完全相同的代码行与不同的奖金拾取与不同的名称,它工作得很好。唯一的区别是其他奖励拾取是使用skshapenode,无论两种方式他们都从sknode继承,所以他们应该都相同的功能。

问题#2:脉动节点成功添加,但只发出几次脉冲,我觉得很奇怪,因为我在不同的奖金上使用了确切的一组skaction,并且奖励脉冲直到从直升机节点移除

1 个答案:

答案 0 :(得分:0)

观察:

您不应该使用NSTimer。而是使用SKScene的update:方法执行定时操作,如果需要,则将其转发给需要它的子节点。或者使用与runBlock排序的SKAction waitForDuration。 NSTimer可能无法与Sprite Kit更新/渲染循环同步运行,并且如果节点或场景暂停,它们将不会停止触发。

检查您是否有多个名为“wearingOut”的子节点。听起来你可能已经添加了多个。使用NSTimer实际上可能会导致奇怪的行为,因为Sprite Kit可能会延迟在场景中添加/删除节点,因此添加/删除节点的时间可能会成为问题。这是一个疯狂的猜测。

脉冲问题也可能表明有多个精灵,也许它们是异步脉动的,所以它们看起来并不是脉动的。或者尝试fadeAlphaTo:操作。

通常尝试使用记录的初始化程序。如果只做[[SKLabelNode alloc] init],可能会出现问题。我遇到了[SKSpriteNode node]的一些问题,即使在设置纹理后也没有绘制。而是执行[SKLabelNode labelNodeWithFontNamed:@"Arial"]或任何其他指定的初始值设定项。请参阅Sprite Kit Framework reference