Sprite Kit 暂停/恢复场景在重启后不起作用

Posted

技术标签:

【中文标题】Sprite Kit 暂停/恢复场景在重启后不起作用【英文标题】:Sprite Kit pause/resume scene isn't working after restart 【发布时间】:2014-07-15 03:48:05 【问题描述】:

我在一个游戏中成功实现了按下主页按钮时的暂停功能。在具有主场景的视图控制器中,我暂停使用:

- (void)appWillEnterBackground
SKView *skView = (SKView *)self.view;
skView.paused = YES;
bubbleOn=NO; //turns bubble spawn off

[[NSNotificationCenter defaultCenter] removeObserver:self];
[[NSNotificationCenter defaultCenter]
 addObserver:self
 selector:@selector(appWillEnterForeground)
 name:UIApplicationDidBecomeActiveNotification
 object:NULL];
    

要取消暂停,

- (void)appWillEnterForeground
SKView * skView = (SKView *)self.view;
skView.paused=NO;
bubbleOn=YES; Allows recursive method to run until bubbleOn = YES
[NSTimer scheduledTimerWithTimeInterval:slowMo target:scene selector:@selector(spawnNew) userInfo:nil repeats:NO]; //Recursive spawn method

[[NSNotificationCenter defaultCenter] removeObserver:self];
[[NSNotificationCenter defaultCenter]
 addObserver:self
 selector:@selector(appWillEnterBackground)
 name:UIApplicationWillResignActiveNotification
 object:NULL];

在我的游戏结束并呈现一个新场景(结束场景)之前,这很好用。结束场景显示分数后,用户可以再次点击以重新开始并呈现主场景。主场景的 initWithSize 方法开始递归方法 spawnNew。如果应用程序进入后台,场景会暂停并 spawnNew 停止。

但是当应用程序进入前台时,场景确实恢复了,但是 spawnNew 方法不起作用。它被调用并输出正确的 NSLog 消息,但该方法不会产生气泡节点。

spawnNew 方法在我的主场景的实现中:

-(void) spawnNew
if (bubbleOn==YES)
    bubble = [SKSpriteNode spriteNodeWithImageNamed:ballName];
    bubble.physicsBody = [SKPhysicsBody bodyWithCircleOfRadius:bubble.size.width/2];
    ...
    //bubble properties
    ...
    [self addChild:bubble];
    NSLog(@"Spawn!");

    [NSTimer scheduledTimerWithTimeInterval:slowMo target:self selector:@selector(spawnNew) userInfo:nil repeats:NO];

    return;
 else
    return;

我现在没有想法!有什么建议么?

【问题讨论】:

不要使用 nstimer,计时器不会暂停 【参考方案1】:

最简单的方法是摆脱NSTimer。您可以改用SKAction

SKSceneinitWithSize方法中:

- (instancetype)initWithSize:(CGSize)size 
    if (self = [super initWithSize:size]) 
        ....

        __weak GameScene *weakSelf = self;
        SKAction *spawnBubble = [SKAction runBlock:^
            [weakSelf spawnNew];
        ];
        SKAction *wait = [SKAction waitForDuration:slowMo];
        [self runAction:[SKAction repeatActionForever:
            [SKAction sequence:@[spawnBubble,wait]]]];
    
    return self;

在这种情况下,您甚至不需要使用 bubbleOn 变量,因为场景会在 SKView 暂停后立即停止执行任何操作。

【讨论】:

你能解释一下你为什么使用 __weak 吗? 为了防止方块保留自我,虽然不确定这里是否有必要但它不会受到伤害 @akashg @LearnCocos2D 我昨天花了一整天的时间找出为什么我的场景没有被释放 :) 原因是 SKAction 块中的保留周期,所以我总是会使用那个修改器. 我之前使用过 SKActions,但是 slowMo 变量会随着分数的增加而变化。变量本身按预期更改,但 SKAction 保留原始 waitForDuration 而不是更新为新的 slowMo 值。在渲染每一帧之前,我是否需要在某处更新 SKAction? 您可以删除该操作并使用更新的 slowMo 值再次添加它

以上是关于Sprite Kit 暂停/恢复场景在重启后不起作用的主要内容,如果未能解决你的问题,请参考以下文章

在 Sprite Kit 中暂停 SKPhysicsWorld

Sprite Kit 最后得分数据

iOS 7 Sprite Kit 释放内存

Sprite Kit 场景未呈现

使用 Swift 在 sprite kit 中的多个场景中重用相同的 sprite 节点

如何在场景中放置场景 - Sprite Kit