Okay, so in my SpriteKit game, I have an SKAction that waits and then calls a method. I have this action repeating forever. The methods spawns sprites. When I press a button (another sprite) the game pauses, and stops the action by removing it. When either resume or restart (also sprites) is pressed the action starts again and the sprites spawn.
However, when returning from the background (after the app is left) and the pause menu method automatically gets called, when I press the resume or restart button, the action does not run for some reason. Here's my code:
In GameScene.m:
-(void)createSceneContents {
self.isPaused = NO;
self.world = [SKNode node];
[self createUI];
[self createPauseMenu];
self.spawningSpeed = 1.5;
self.enemyData = [[Enemy alloc]init];
SKAction *wait = [SKAction waitForDuration:self.spawningSpeed];
SKAction *run = [SKAction performSelector:@selector(spawningEnemy) onTarget:self];
self.spawnAction = [SKAction repeatActionForever:[SKAction sequence:@[wait,run]]];
[self.world runAction:self.spawnAction withKey:@"spawn"];
[[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(wentToForeground) name:UIApplicationWillEnterForegroundNotification object:nil];
[self addChild:self.world];
[self.world addChild:bottom];
[self.world addChild:self.player];
[self addChild:left];
[self addChild:right];
[self addChild:self.pause];
[self addChild:self.scoreLabelInGame];
[self addChild:self.actualScore];
}
-(void)createUI {
self.pause = [SKSpriteNode spriteNodeWithImageNamed:@"pausebutton.png"];
self.pause.size = CGSizeMake(self.customUnit,self.customUnit);
self.pause.name = @"pauseButton";
self.pause.position = CGPointMake(30, self.frame.size.height - 30);
self.scoreLabelInGame = [SKLabelNode labelNodeWithFontNamed:@"Futura"];
self.scoreLabelInGame.text = @"";
self.scoreLabelInGame.fontSize = 25;
self.scoreLabelInGame.position = CGPointMake(self.frame.size.width - 100, self.frame.size.height - 40);
self.actualScore = [SKLabelNode labelNodeWithFontNamed:@"Futura"];
self.actualScore.text = @"SCORE: 0";
self.actualScore.fontSize = 25;
self.actualScore.horizontalAlignmentMode = SKLabelHorizontalAlignmentModeRight;
self.actualScore.position = CGPointMake(self.frame.size.width - 20, self.frame.size.height - 40);
self.deathImage = [SKSpriteNode spriteNodeWithImageNamed:@"youdied.png"];
self.deathImage.position = CGPointMake(CGRectGetMidX(self.frame), CGRectGetMidY(self.frame)*1.5);
}
-(void)createPauseMenu {
self.pausedImage = [SKSpriteNode spriteNodeWithImageNamed:@"paused.png"];
self.pausedImage.position = CGPointMake(CGRectGetMidX(self.frame), CGRectGetMidY(self.frame)*1.5);
self.restart = [SKLabelNode labelNodeWithFontNamed:@"Futura"];
self.restart.text = @"RESTART";
self.restart.fontSize = 25;
self.restart.position = CGPointMake(CGRectGetMidX(self.frame), self.pausedImage.position.y - self.pausedImage.position.y/5);
self.resume = [SKLabelNode labelNodeWithFontNamed:@"Futura"];
self.resume.text = @"RESUME";
self.resume.fontSize = 25;
self.resume.position = CGPointMake(self.restart.position.x, self.restart.position.y - self.customUnit);
}
-(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];
}
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = [touches anyObject];
CGPoint location = [touch locationInNode:self];
if([self.pause containsPoint:location] && self.isPaused == NO){
[self pauseGame];
}else if([self.resume containsPoint:location] && self.isPaused == YES) {
[self resumeGame];
}else if ([self.restart containsPoint:location] && self.isPaused == YES){
[self restartGame];
}else if (self.isTouchingGround == YES && self.isPaused == NO) {
[self.playerData jump:self.player];
NSLog(@"GOD YES");
self.isTouchingGround = NO;
}
}
-(void)pauseGame {
[self createPauseMenu];
NSLog(@"Pausing...");
[self removeActionForKey:@"spawn"];
self.world.paused = YES;
[self addChild:self.pausedImage];
[self addChild:self.restart];
[self addChild:self.resume];
NSString *path = [NSString stringWithFormat:@"%@/menu_music.mp3", [[NSBundle mainBundle]resourcePath]];
NSURL *pauseMusicURL = [NSURL fileURLWithPath:path];
self.pauseMusicPlayer = [[AVAudioPlayer alloc]initWithContentsOfURL:pauseMusicURL error:nil];
self.pauseMusicPlayer.numberOfLoops = -1;
[self.pauseMusicPlayer play];
[self.pause removeFromParent];
self.scoreLabelInGame.position = CGPointMake(self.restart.position.x, self.resume.position.y - self.customUnit);
self.actualScore.position = CGPointMake(self.restart.position.x, self.scoreLabelInGame.position.y - self.customUnit);
self.isPaused = YES;
[self.mainMusicPlayer pause];
}
-(void)restartGame {
[self removeAllChildren];
[self removeAllActions];
self.enemyData = nil;
self.isPaused = NO;
[self.pauseMusicPlayer stop];
[self createSceneContents];
[self runAction:self.spawnAction withKey:@"spawn"];
}
-(void)resumeGame {
self.isPaused = NO;
[self.pauseMusicPlayer stop];
[self runAction:self.spawnAction withKey:@"spawn"];
self.scoreLabelInGame.position = CGPointMake(self.frame.size.width - 100, self.frame.size.height - 40);
self.actualScore.position = CGPointMake(self.frame.size.width - 20, self.frame.size.height - 40);
[self.mainMusicPlayer play];
[self.restart removeFromParent];
[self.resume removeFromParent];
[self.pausedImage removeFromParent];
[self addChild:self.pause];
}
-(void)gameOver {
NSLog(@"Game Over");
GameDataHelper *gameData = [[GameDataHelper alloc]init];
[self removeActionForKey:@"spawn"];
[self addChild:self.restart];
[self addChild:self.deathImage];
SKAction *gameOverSound = [SKAction playSoundFileNamed:@"gameover_tune.mp3" waitForCompletion:NO];
[self runAction:gameOverSound];
NSString *path = [NSString stringWithFormat:@"%@/menu_music.mp3", [[NSBundle mainBundle]resourcePath]];
NSURL *pauseMusicURL = [NSURL fileURLWithPath:path];
self.pauseMusicPlayer = [[AVAudioPlayer alloc]initWithContentsOfURL:pauseMusicURL error:nil];
self.pauseMusicPlayer.numberOfLoops = -1;
[self.pauseMusicPlayer play];
[self.pause removeFromParent];
SKLabelNode *highScore = [SKLabelNode labelNodeWithFontNamed:@"Futura"];
NSString *highScoreText = [NSString stringWithFormat:@"HIGHSCORE: %ld",[GameDataHelper sharedGameData].highScore];
highScore.text = highScoreText;
highScore.fontSize = 25;
highScore.position = CGPointMake(self.frame.size.width/2, self.restart.position.y - (2*self.customUnit));
[self addChild:highScore];
self.scoreLabelInGame.position = CGPointMake(self.restart.position.x, self.resume.position.y - self.customUnit);
self.actualScore.position = CGPointMake(self.restart.position.x, self.scoreLabelInGame.position.y - self.customUnit);
self.isPaused = YES;
[self.mainMusicPlayer pause];
[gameData save];
}
-(void)wentToForeground {
[self pauseGame];
}
In Enemy.m:
-(SKSpriteNode *)createEnemyWithSize:(float)size andWidth:(float)width andHeight:(float)height {
self.enemy = [SKSpriteNode spriteNodeWithImageNamed:@"block.png"];
self.enemy.size = CGSizeMake(size - 5, size - 5);
self.enemy.name = @"fallingEnemy";
self.enemy.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:CGSizeMake(size - 3, size - 3)];
self.enemy.physicsBody.restitution = 0;
self.enemy.physicsBody.allowsRotation = NO;
int randomSection = arc4random_uniform(7);
switch (randomSection) {
case 0:
self.enemy.position = CGPointMake(2.5 + self.enemy.size.width/2, height-5);
break;
case 1:
self.enemy.position = CGPointMake(width/7 + self.enemy.size.width/2, height-5);
break;
case 2:
self.enemy.position = CGPointMake((width/7*2) + self.enemy.size.width/2, height-5);
break;
case 3:
self.enemy.position = CGPointMake((width/7*3) + self.enemy.size.width/2, height-5);
break;
case 4:
self.enemy.position = CGPointMake((width/7*4) + self.enemy.size.width/2, height-5);
break;
case 5:
self.enemy.position = CGPointMake((width/7*5) + self.enemy.size.width/2, height-5);
break;
case 6:
self.enemy.position = CGPointMake((width/7*6) + self.enemy.size.width/2, height-5);
break;
default:
break;
}
return self.enemy;
}