我正在为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,并且奖励脉冲直到从直升机节点移除
答案 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。