暂停应用程序启动/退出spritekit游戏.. iOS8

我已经阅读了关于这个主题的所有内容,但仍然无法解决我的问题。 我已经尝试在appdelegate的每个区域暂停我的游戏

func applicationWillResignActive(application: UIApplication!) { NSNotificationCenter.defaultCenter().postNotificationName("pauseGameScene", object: self) } func applicationDidEnterBackground(application: UIApplication!) { NSNotificationCenter.defaultCenter().postNotificationName("pauseGameScene", object: self) } func applicationWillEnterForeground(application: UIApplication!) { NSNotificationCenter.defaultCenter().postNotificationName("pauseGameScene", object: self) } func applicationDidBecomeActive(application: UIApplication!) { NSNotificationCenter.defaultCenter().postNotificationName("pauseGameScene", object: self) } 

在我的控制器中:

 override func viewDidLoad() { NSNotificationCenter.defaultCenter().addObserver(self, selector: "pauseGame:", name: "pauseGameScene", object: nil) } func pauseGame(){ self.skView.paused = true self.skView.scene!.paused = true } 

我知道暂停游戏的作品,因为如果我用我的场景中的button切换它,它会停止游戏。 即使我在加载控制器后直接暂停我的skview和场景,游戏也不会在启动时暂停。 当我在游戏中时,暂停游戏很容易。 但由于某种原因,当我退出并恢复应用程序时,游戏将不会暂停。

我注意到,如果我得到哈克,并使用某种延迟..我可以得到它的工作。 但显然这是非常愚蠢的..我只是需要知道游戏是什么地方是没有rest的!

 func delay(delay:Double, closure:()->()) { dispatch_after( dispatch_time( DISPATCH_TIME_NOW, Int64(delay * Double(NSEC_PER_SEC)) ), dispatch_get_main_queue(), closure) } func pauseGame(sender: UIButton!){ delay(2) { println("blah") self.skView.paused = true self.skView.scene!.paused = true } } 

这是从后台模式返回后保持视图暂停的一种方法。

Xcode 7 (请参阅下面的Xcode 8说明)

在故事板中,

1)将视图的类更改为MyView

在View Controller中,

2)定义一个名为stayPaused的布尔型SKView子类

 class MyView: SKView { var stayPaused = false override var paused: Bool { get { return super.paused } set { if (!stayPaused) { super.paused = newValue } stayPaused = false } } func setStayPaused() { if (super.paused) { self.stayPaused = true } } } 

3)将视图定义为MyView

4)添加一个通知程序来设置stayPaused标志

 class GameViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() if let scene = GameScene.unarchiveFromFile("GameScene") as? GameScene { // Configure the view. let skView = self.view as MyView NSNotificationCenter.defaultCenter().addObserver(skView, selector:Selector("setStayPaused"), name: "stayPausedNotification", object: nil) 

在App Delegate中,

5)发布通知,在应用程序激活时设置停留暂停标志

 func applicationDidBecomeActive(application: UIApplication) { NSNotificationCenter.defaultCenter().postNotificationName("stayPausedNotification", object:nil) } 

Xcode 8

在故事板中,

1)将视图的类从SKViewMyView

在View Controller中,

2)定义一个名为stayPaused的布尔型SKView子类

类MyView:SKView {var stayPaused = false

  override var isPaused: Bool { get { return super.isPaused } set { if (!stayPaused) { super.isPaused = newValue } stayPaused = false } } func setStayPaused() { if (super.isPaused) { self.stayPaused = true } } } 

3)将视图定义为MyView

4)添加一个通知程序来设置stayPaused标志

 class GameViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() if let view = self.view as! MyView? { NotificationCenter.default.addObserver(view, selector:#selector(MyView.setStayPaused), name: NSNotification.Name(rawValue: "stayPausedNotification"), object: nil) 

在App Delegate中,

5)发布通知,在应用程序激活时设置停留暂停标志

 func applicationDidBecomeActive(_ application: UIApplication) { // 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. NotificationCenter.default.post(name: NSNotification.Name(rawValue: "stayPausedNotification"), object: nil) } 

这是一个完全基于0x141E给出的答案的Obj-C示例,没有inheritance一个视图。 在我的情况下,因为我有内部的游戏状态,如完成,暂停和开始,我不得不在重写的setPaused:方法进行额外的检查。 但是,这对我来说是完美无缺的,绝对是一个可行的方法。

AppDelegate.m

 - (void)applicationDidBecomeActive:(UIApplication *)application { [[NSNotificationCenter defaultCenter] postNotificationName:@"stayPausedNotification" object:nil]; } 

GameScene.m

 @interface GameScene() @property (nonatomic, assign) BOOL stayPaused; @end @implementation GameScene //Use initWithCoder: if you load a scene from .sks file, because initWithSize is not called in that case. -(instancetype)initWithSize:(CGSize)size{ if(self = [super initWithSize:size]){ _stayPaused = NO; //register to listen for event [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(setStayPaused) name:@"stayPausedNotification" object:nil ]; } return self; } -(void)setStayPaused{ self.stayPaused = YES; } -(void)setPaused:(BOOL)paused{ if (!self.stayPaused) { [super setPaused:paused]; } self.stayPaused = NO; } -(void)willMoveFromView:(SKView *)view{ [[NSNotificationCenter defaultCenter] removeObserver:self name:@"stayPausedNotification" object:nil]; } @end 

我最近遇到了同样的问题。 stayPaused解决scheme适合我。 多谢你们:)

不过,我认为你用来设置stayPaused的机制不健壮。 仅仅通过调用setStayPaused在应用程序激活之后是不够的,苹果公司的工程师可能会改变Sprite Kit的代码,并且在激活时调用setPaused(false)多于一次(实际上,我认为他们只是做了!)。 第二个setPaused(false)会在第一次调用时将stayPaused设置回false。

我的build议是直接在暂停游戏/ resumeGame函数中设置stayPaused属性,并删除“self.stayPaused = NO;” from setPaused函数。 通过这种方式,SpriteKit的默认行为可以做任何喜欢的事情,但是只要我们想要,游戏就会保持暂停。