SpriteKit-多任务的正确方法

时间:2013-09-25 19:52:38

标签: background ios7 sprite-kit

我试图在代码中的任何地方进行搜索:解释文档在进入后台时的作用,或者某些时候是否暂停,但无济于事 - 有人指导我去做推荐的去做的方式在sprite kit启用游戏中的背景?

我应该只是致电scene.paused = YES,或者如何确认背景中没有绘图,这样我就可以避免iOS终止而不允许我这样做?

谢谢!

6 个答案:

答案 0 :(得分:39)

SpriteKit实际上还没有记录,可能是因为它太新了,相对较少的开发人员已经实现了它。 SpriteKit 应该在后台运行时暂停动画,但根据我的经验(和harrym17's),它会导致内存访问错误并完全退出应用程序而不是后台处理。

根据Apple开发者论坛的说法,这似乎是SpriteKit中的一个已知错误(它并不总是在后台时暂停动画,因为它应该)导致memory access errors as per harrym17's comment。这是一个简单的解决方案,对我有用 - 我的应用程序在后台时一直崩溃,并且因为添加此代码一切正常。

(对于Apple论坛上的此代码感谢Keith Murray;据我所知,他没有在SO上发布此代码。)

AppDelegate.h中,请确保导入SpriteKit:

#import <SpriteKit/SpriteKit.h>

AppDelegate.m中,修改您的applicationWillResignActive方法:

- (void)applicationWillResignActive:(UIApplication *)application
{
     // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
     // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.

     // pause sprite kit
     SKView *view = (SKView *)self.window.rootViewController.view;
     view.paused = YES;
}

这是你的applicationDidBecomeActive方法:

- (void)applicationDidBecomeActive:(UIApplication *)application
{
     // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.

     // resume sprite kit
     SKView *view = (SKView *)self.window.rootViewController.view;
     view.paused = NO;
}

显然,通过AVAudioSession播放音频时的背景存在其他问题;提到了一种解决方法in this thread

答案 1 :(得分:14)

正如LearnCocos2D所述here

  

问题是当应用程序进入后台时AVAudioSession无法激活。

     

修复非常简单,也适用于ObjectAL =&gt;当应用程序处于后台时,将AVAudioSession设置为非活动状态,并在应用程序进入前台时重新激活音频会话。

     

使用此修复程序的简化AppDelegate如下所示:

#import <AVFoundation/AVFoundation.h>

...

- (void)applicationWillResignActive:(UIApplication *)application
{
    // prevent audio crash
    [[AVAudioSession sharedInstance] setActive:NO error:nil];
}

- (void)applicationDidEnterBackground:(UIApplication *)application
{
    // prevent audio crash
    [[AVAudioSession sharedInstance] setActive:NO error:nil];
}

- (void)applicationWillEnterForeground:(UIApplication *)application
{
    // resume audio
    [[AVAudioSession sharedInstance] setActive:YES error:nil];
}
  

PS:此修复程序将包含在Kobold Kit v7.0.3中。

答案 2 :(得分:10)

我想知道为什么世界上这个看似简单的解决方案导致我在应用启动时崩溃,但这是因为我有iAd运行。 所以,要记住一件事:@ MassivePenguin的答案有效,但如果你有iAd ,你必须通过SKView抓住subviews或者(显然)崩溃

-(SKView*)getSKViewSubview{
    for (UIView* s in self.window.rootViewController.view.subviews) {
        if ([s isKindOfClass:[SKView class]]) {
            return (SKView*)s;
        }
    }
    return nil;
}

- (void)applicationWillResignActive:(UIApplication *)application {    
    SKView* view = [self getSKViewSubview];

    if (view) {
        view.paused = YES;
    }

}

- (void)applicationDidBecomeActive:(UIApplication *)application
{
    SKView* view = [self getSKViewSubview];

    if (view) {
        view.paused = NO;
    }

}

答案 3 :(得分:1)

对我来说没有提供任何解决方案。我确实找到了另一种方法。

// In the AppDelegate
- (void)applicationWillResignActive:(UIApplication *)application
{
    if ([self.window.rootViewController isKindOfClass:[GameViewController class]]) {
        GameViewController *vc = (GameViewController*)self.window.rootViewController;
        [vc pauseGame];
        [vc.view addObserver:vc
                  forKeyPath:@"paused"
                     options:NSKeyValueObservingOptionNew
                     context:nil];
    }
}

// In the GameViewController
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
    SKView *skView = (SKView*)self.view;
    MainGame *mainGame = (MainGame*)skView.scene;
    if ([keyPath isEqualToString:@"paused"] &&
        [[change objectForKey:NSKeyValueChangeNewKey] boolValue] == NO &&
        [mainGame isGameInProgress]) {
        [self.view removeObserver:self forKeyPath:@"paused" context:nil];
        skView.paused = YES;
    }
}

答案 4 :(得分:0)

iPad的背景似乎还不错,但iPhone背景精灵套装游戏肯定会崩溃。您必须手动执行此操作,自动化部件不是那么自动化。

答案 5 :(得分:-4)

Sprite Kit在移动到后台时会自动暂停其动画定时器 - 您无需担心应用程序因此而被杀死。