什么导致我的SKAction计时器行为奇怪?
好吧,我有一个场景,我有这个方法, createSceneContents , didMoveToView被调用时被调用。 在这个方法中,我有一些创build场景的东西,其中包括一个像这样产生节点的计时器:
self.spawningSpeed = 1.5; self.enemyData = [[Enemy alloc]init]; SKAction *wait = [SKAction waitForDuration:1.5]; SKAction *run = [SKAction performSelector:@selector(spawningEnemy) onTarget:self]; self.spawnAction = [SKAction repeatActionForever:[SKAction sequence:@[wait,run]]]; [self.world runAction:self.spawnAction withKey:@"spawn"];
enemyData是我的敌人级别的一个物体,基本上只是在场景中增加一个SKSpriteNode。 世界节点就是我添加所有游戏元素的节点。
这就是在spawningEnemy方法中发生的事情:
-(void)spawningEnemy { NSLog(@"spawned"); SKSpriteNode *aNewEnemy = [self.enemyData createEnemyWithSize:self.customUnit andWidth:self.frame.size.width andHeight:self.frame.size.height + self.player.position.y]; aNewEnemy.physicsBody.allowsRotation = NO; aNewEnemy.physicsBody.categoryBitMask = self.enemyCategory; aNewEnemy.physicsBody.collisionBitMask = self.enemyCategory | self.playerCategory | self.edgeCategory | self.bottomCategory; aNewEnemy.physicsBody.contactTestBitMask = self.enemyCategory | self.playerCategory | self.edgeCategory | self.bottomCategory; [self.world addChild:aNewEnemy]; }
这只是从敌人类获得一个SKSpriteNode并设置一些属性。 它也将其添加到世界。
我也有4种方法暂停,恢复,重新开始和游戏结束游戏:
-(void)pauseGame { [self createPauseMenu]; NSLog(@"Pausing..."); self.world.paused = YES; self.isPaused = YES; } -(void)restartGame { [self removeAllChildren]; [self removeAllActions]; self.enemyData = nil; self.isPaused = NO; [self createSceneContents]; } -(void)resumeGame { self.isPaused = NO; self.world.paused = NO; } -(void)gameOver { NSLog(@"Game Over"); self.world.paused = YES; self.isPaused = YES; }
这些方法还有更多,但这是真正重要的。
现在,这是问题:这一切工作正常,直到我退出应用程序。 当返回到应用程序时,游戏会自动调用暂停方法,但是当我重新启动或恢复时,不会调用spawningEnemy方法。 (我可以看到,我使用NSLog消息进行了检查)
这可能是什么原因造成的?
我已经尝试了下面的代码,它的工作原理。 当应用程序停止活动时,产卵停止,并且一旦应用程序再次变为活动状态,则会自动重新启动。
您不需要手动添加代码来暂停,因为SpriteKit会在退出活动时自行暂停,但是我将其包括在内以显示AppDelegate和SKScene之间的通信方式。
AppDelegate.m
- (void)applicationWillResignActive:(UIApplication *)application { [[NSNotificationCenter defaultCenter]postNotificationName:@"applicationWillResignActive" object:self]; } - (void)applicationDidBecomeActive:(UIApplication *)application { [[NSNotificationCenter defaultCenter]postNotificationName:@"applicationDidBecomeActive" object:self]; }
GameScene.m
-(id)initWithSize:(CGSize)size { if (self = [super initWithSize:size]) { SKAction *wait = [SKAction waitForDuration:1.5]; SKAction *run = [SKAction performSelector:@selector(spawningEnemy) onTarget:self]; SKAction *spawnAction = [SKAction repeatActionForever:[SKAction sequence:@[wait,run]]]; [self runAction:spawnAction withKey:@"spawn"]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(pauseGame) name:@"applicationWillResignActive" object:nil]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(resumeGame) name:@"applicationDidBecomeActive" object:nil]; } return self; } -(void)spawningEnemy { NSLog(@"spawningEnemy"); } -(void)pauseGame { NSLog(@"applicationWillResignActive..."); self.paused = YES; } -(void)resumeGame { NSLog(@"applicationDidBecomeActive..."); self.paused = NO; } -(void)willMoveFromView:(SKView *)view { // good housekeeping [[NSNotificationCenter defaultCenter] removeObserver:self]; }
如果是想要暂停的整个场景,则只应暂停包含场景的SKView。 这将暂停所有的animation,运行循环和场景内的所有节点的交互。
还有经验告诉我,当应用程序进入后台时暂停场景并在回到前台时恢复是一个好习惯。 它可以防止以下问题: Sprite Kit和播放声音导致应用程序终止