正如标题所暗示的那样,当我的游戏进入后台时,我试图阻止我的NSTimer,并在游戏重新开始时重新开始。中断显然可能是接听电话等。
我在app delegate中使用以下代码在应用程序被中断时停止并重新启动场景,但它不会停止计时器。
- (void)applicationWillResignActive:(UIApplication *)application {
SKView *view = (SKView *)self.window.rootViewController.view;
view.scene.paused = YES;
}
- (void)applicationDidBecomeActive:(UIApplication *)application {
SKView *view = (SKView *)self.window.rootViewController.view;
view.scene.paused = NO;
}
在我放置计时器的场景中,我已将观察者放在-(id)initWithSize:(CGSize)size
方法中。以下是观察员:
[[NSNotificationCenter defaultCenter]
addObserver:self
selector:@selector(goBackground)
name:UIApplicationDidEnterBackgroundNotification
object:nil];
[[NSNotificationCenter defaultCenter]
addObserver:self
selector:@selector(backBackground)
name:UIApplicationDidBecomeActiveNotification object:nil];
和选择器方法:
- (void) goBackground {
[timer invalidate], timer = nil;
}
- (void) backBackground {
if([timer isValid]) {
[timer invalidate];
}
timer = [NSTimer scheduledTimerWithTimeInterval:1.0f target:self selector:@selector(updateCounter:) userInfo:nil repeats:YES];
}
我也试图按如下方式取消分配观察员:
- (void)dealloc {
[[NSNotificationCenter defaultCenter] removeObserver:self name:UIApplicationWillResignActiveNotification object:nil];
[[NSNotificationCenter defaultCenter] removeObserver:self name:UIApplicationDidBecomeActiveNotification object:nil];
}
上面的代码被触发,我已经在所有上述方法上放置了一个NSLog。但是会发生什么,它适用于场景1,它是1级的地方,当玩家赢得1级并进入2级并且我再次重新创建应用程序中断场景时,它会回来并在游戏前工作几秒钟崩溃。
显然我的代码不起作用,我已经尝试过每一种我知道如何解决这个问题的方法,但无济于事。我所拥有的计时器只是为了显示该级别剩余多少时间而与获胜/失败情景无关。(这可能是一些额外的信息,可能不需要知道)。
无论如何,当我的游戏进入后台时,我可以停止并重启我的计时器吗?我真的很感激任何帮助。
我不知道是否需要定时器代码但是如下:
- (void) gameTimerLabel {
gameTimerLabel = [SKLabelNode labelNodeWithFontNamed:@"ArialRoundedMTBold"];
// gameTimerLabel.text = [NSString stringWithFormat:@"%d", _lives];
gameTimerLabel.fontSize = 20.0;
gameTimerLabel.fontColor = [SKColor colorWithRed:135.0/255 green:207.0/255 blue:232.0/255 alpha:0.6];
gameTimerLabel.position = gameTimerLabel.position = CGPointMake(270, 282);
[self addChild:gameTimerLabel];
}
- (void)updateCounter:(NSTimer *)theTimer {
if(secondsLeft > 0 ){
secondsLeft -- ;
//hours = secondsLeft / 3600;
minutes = (secondsLeft % 3600) / 60;
seconds = (secondsLeft %3600) % 60;
gameTimerLabel.text = [NSString stringWithFormat:@"%02d:%02d", minutes, seconds];
}
else{
secondsLeft = 70;
}
}
-(void)countdownTimer{
secondsLeft = hours = minutes = seconds = 0;
if([timer isValid]) {
[timer invalidate];
}
timer = [NSTimer scheduledTimerWithTimeInterval:1.0f target:self selector:@selector(updateCounter:) userInfo:nil repeats:YES];
}
它基本上只是一个倒数计时器,没什么特别的。
编辑:
Ben-G,是对的。几乎没有办法在后台/前台管理NSTimer,所以我使用了SKAction方法并完成了工作。对于那些感兴趣的人,这是工作代码:@implementation MyScene {
SKLabelNode *gameTimerLabel;
int countDownInt;
int secondsLeft;
}
-(id)initWithSize:(CGSize)size {
if (self = [super initWithSize:size]) {
secondsLeft = 70;
[self gameTimerLabel];
}
return self;
}
- (void) gameTimerLabel {
gameTimerLabel = [SKLabelNode labelNodeWithFontNamed:@"ArialRoundedMTBold"];
gameTimerLabel.fontSize = 20.0;
gameTimerLabel.fontColor = [SKColor colorWithRed:135.0/255 green:207.0/255 blue:232.0/255 alpha:0.6];
gameTimerLabel.position = gameTimerLabel.position = CGPointMake(270, 282);
[self addChild:gameTimerLabel];
countDownInt = secondsLeft;
SKAction *updateLabel = [SKAction runBlock:^{
gameTimerLabel.text = [NSString stringWithFormat:@" %02d", countDownInt];
--countDownInt;
}];
SKAction *wait = [SKAction waitForDuration:1.0];
SKAction *updateLabelAndWait = [SKAction sequence:@[updateLabel, wait]];
[self runAction:[SKAction repeatAction:updateLabelAndWait count:secondsLeft] completion:^{
gameTimerLabel.text = @"Time's Up";
}];
}
这就是全部。再次感谢Ben-G指出我正确的方向。
答案 0 :(得分:4)
即使它没有完全回答你的问题,我也会参考这个问题的接受答案:SpriteKit - Creating a timer。
通常,您希望在使用游戏引擎时避免使用NSTimer
。您的定时动作不会与游戏循环集成,并且在游戏暂停时您的计时器不会自动停止。
而是与update
方法集成或使用SKAction
。