我正在做一个即将完成的游戏,但我遇到了一个问题,我无法解决自己(老实说,存在多重问题,但让我们把这个问题留给其他问题吧)。
我的游戏是这样组织的: MainMenu -> GameScene --> nodes / GameOver暂停和GameOver菜单基本上是由雪碧和标签节点组成的。
在游戏中,有一个玩家需要避免接触敌人,每x个时间就产生一次。我通过重复一个永远运行代码块的SKAction来实现这一点。
当游戏暂停(当暂停按钮被击中)时,它会将布尔值(isPaused)更改为是,这会导致所有方法停止。它也移除敌人的产卵行动。
当游戏重新启动时,它会删除当前存在的所有内容,并重新创建整个场景。
这里的问题是:每当我单击“暂停”按钮时,就会显示出菜单,然后退出应用程序(只是背景,而不是实际退出),然后返回并按重新启动,敌人不会产生ergo,操作也不会运行(节点计数也不会上升)。
,以下是一些代码:
我不会把所有的东西都放进去,所以如果你找到了一些引用不存在的东西,那么这个东西很可能就在原始代码中。
在GameScene.m中:
-(void)didMoveToView:(SKView *)view {
if (!self.contentCreated) {
[self createSceneContents];
self.contentCreated = YES;
}
}
-(void)createSceneContents {
self.isTouchingGround = NO;
self.isPaused = NO;
self.world = [SKNode node];
NSLog(@"likewhatever");
self.playerCategory = 1;
self.enemyCategory = 2;
self.edgeCategory = 4;
self.bottomCategory = 8;
self.playerScore = 0;
[GameDataHelper sharedGameData].score = 0;
self.physicsWorld.contactDelegate = self;
SKSpriteNode *bottom = [SKSpriteNode spriteNodeWithColor:[SKColor blackColor] size:CGSizeMake(self.frame.size.width, 10)];
bottom.position = CGPointMake(self.frame.size.width/2, 0);
bottom.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:bottom.size];
bottom.physicsBody.dynamic = NO;
bottom.physicsBody.restitution = 0;
bottom.physicsBody.categoryBitMask = self.bottomCategory;
bottom.physicsBody.contactTestBitMask = self.playerCategory | self.enemyCategory;
SKSpriteNode *left = [[SKSpriteNode alloc]init];
left.size = CGSizeMake(1, self.frame.size.height);
left.position = CGPointMake(0, self.frame.size.height/2);
left.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:left.size];
left.physicsBody.dynamic = NO;
left.physicsBody.restitution = 0;
SKSpriteNode *right = [[SKSpriteNode alloc]init];
right.size = CGSizeMake(1, self.frame.size.height);
right.position = CGPointMake(self.frame.size.width - 1, self.frame.size.height/2);
right.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:right.size];
right.physicsBody.dynamic = NO;
right.physicsBody.restitution = 0;
self.backgroundColor = [SKColor blackColor];
self.playerData = [[Player alloc]init];
self.customUnit = self.frame.size.width/7;
self.player = [self.playerData newPlayer:self.customUnit];
self.player.physicsBody.categoryBitMask = self.playerCategory;
self.player.physicsBody.contactTestBitMask = self.enemyCategory | self.edgeCategory | self.bottomCategory;
self.player.position = CGPointMake(CGRectGetMidX(self.frame), self.customUnit*5);
[self.playerData movementSetup];
[self createUI];
NSString *path = [NSString stringWithFormat:@"%@/gamemusic2.mp3", [[NSBundle mainBundle]resourcePath]];
NSURL *mainMusicURL = [NSURL fileURLWithPath:path];
self.mainMusicPlayer = [[AVAudioPlayer alloc]initWithContentsOfURL:mainMusicURL error:nil];
self.mainMusicPlayer.volume = 0.1;
self.mainMusicPlayer.numberOfLoops = -1;
[self.mainMusicPlayer play];
[self spawnObject];
[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.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);
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)spawnObject {
NSLog(@"called");
if (self.isPaused == NO){
NSLog(@"notpaused");
self.spawningSpeed = 1.5;
self.enemyData = [[Enemy alloc]init];
SKAction *wait = [SKAction waitForDuration:self.spawningSpeed];
SKAction *run = [SKAction runBlock:^{
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];
}];
SKAction *action = [SKAction repeatActionForever:[SKAction sequence:@[wait,run]]];
[self runAction:action withKey:@"spawn"];
}
}
-(void)didBeginContact:(SKPhysicsContact *)contact {
if (self.isPaused == NO) {
SKPhysicsBody *firstBody, *secondBody;
if (contact.bodyA.categoryBitMask < contact.bodyB.categoryBitMask) {
firstBody = contact.bodyA;
secondBody = contact.bodyB;
}else {
firstBody = contact.bodyB;
secondBody = contact.bodyA;
}
if (firstBody.categoryBitMask == self.playerCategory && secondBody.categoryBitMask == self.bottomCategory) {
self.isTouchingGround = YES;
}
if (firstBody.categoryBitMask == self.playerCategory && secondBody.categoryBitMask == self.enemyCategory) {
self.isTouchingGround = YES;
if ([secondBody.node.name isEqualToString:@"fallingEnemy"] && self.player.position.y < secondBody.node.position.y) {
[self gameOver];
}
}
if (firstBody.categoryBitMask == self.enemyCategory && secondBody.categoryBitMask == self.enemyCategory) {
[self.enemyData changeBlock:firstBody.node];
[self.enemyData changeBlock:secondBody.node];
[self impactSound];
[self updateScore];
NSLog(@"Change1");
}
if (firstBody.categoryBitMask == self.enemyCategory && secondBody.categoryBitMask == self.bottomCategory) {
NSLog(@"Change2");
[self.enemyData changeBlock:firstBody.node];
[self impactSound];
[self updateScore];
}
}
}
-(void)pauseGame {
NSLog(@"Pausing...");
[self removeActionForKey:@"spawn"];
[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.isPaused = NO;
[self.pauseMusicPlayer stop];
[self createSceneContents];
}
-(void)resumeGame {
self.isPaused = NO;
[self.pauseMusicPlayer stop];
[self spawnObject];
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];
}在敌人:
-(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;
}
-(void)changeBlock:(SKNode *)block{
block.physicsBody.dynamic = NO;
block.name = @"staticEnemy";
}发布于 2015-02-15 02:15:56
我和你有一个非常相似的问题(并且注意到你的其他问题都是类似的)。幸运的是,我能够解决这个问题,并希望我能为你提供一些见解。
我的情况:,我正在创建一个基于物理的游戏,它使用粒子发射器和SKActions来处理游戏的某些方面。然而,我注意到这些“破坏”是在从insactive返回时发生的;也就是说,尽管所有属性在进入背景之前和之后都是相同的,但是粒子发射器没有显示任何东西,而且即使在从不活动状态返回后初始化它们,SKActions也不能工作。和你一样,我使用了一个自定义的"isPaused“变量来维护游戏状态。
My解决方案:将"isPaused“标志的名称更改为"gameIsPaused”。
,为什么?,我的研究让我相信,这与场景如何保持在孩子身上,以及SpriteKit进入后台时所做的事情有关。虽然苹果并没有公布幕后发生的事情,但各种论坛似乎都表明,当应用程序变得不活跃时,SpriteKit会自动暂停这一场景。
但是,通过拥有自己的"isPaused“变量,我认为您正在踩到一些导致bug的底层过程。
其他利用NSNotification中心(What is causing my SKAction timer to behave strangely?)的解决方案会像预期的那样重新命名"isPaused“标志。
https://stackoverflow.com/questions/28050522
复制相似问题