Приостановка игры 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
}

Я знаю, что pauseGame работает, потому что если я переключу его с помощью кнопки на моей сцене, это остановит игру. Даже если я приостановил свой просмотр и сцену сразу после их загрузки в контроллер. Игра не будет приостановлена ​​при запуске. Легко приостановить игру, когда я играю в игру. но по какой-то причине, когда я выхожу и возобновляю приложение, игра будет отключена.

Я замечаю, что если я получаю хакерство и использую какую-то задержку, я могу заставить его работать. но, очевидно, это очень глупо. Мне просто нужно знать, где игра сама себя разочаровывает!

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

Здесь можно приостановить просмотр после возвращения из фонового режима.

Xcode 7 (см. ниже инструкции Xcode 8)

В раскадровке

1) Измените класс представления на MyView

В контроллере просмотра

2) Определите подкласс SKView с булевым именем stayPaused

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)

В приложении Appate,

5) Отправьте уведомление, чтобы установить флаг приостановки пребывания, когда приложение становится активным.

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

Xcode 8

В раскадровке

1) Измените класс представления с SKView на MyView

В контроллере просмотра

2) Определите подкласс SKView с булевым именем stayPaused

класс 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)

В приложении Appate,

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)
}


Вот пример Obj-C, полностью основанный на ответе, заданном 0x141E, без подкласса представления. В моем случае, поскольку у меня есть внутренние игровые состояния, например, законченные, приостановленные и начатые, мне пришлось сделать дополнительную проверку в переопределенном методе 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 отлично работает для меня. Спасибо, ребята:)

Однако, я думаю, что механизм, который вы используете для установки stayPaused, не является надежным. Просто, вызвав setStayPaused, когда приложение становится активным, недостаточно, инженеры из Apple могут изменить код набора Sprite и вызвать setPaused (false) БОЛЬШЕ, ЧЕМ ОДИН РАЗ АКТИВИЗАЦИИ (На самом деле, я думаю, они только что сделали!). Второй setPaused (false) возобновит игру, поскольку при первом вызове вы установите для параметра stayPaused значение false.

Мое предложение - прямо установить свойство stayPaused самостоятельно в своих функциях pauseGame/resumeGame и удалить "self.stayPaused = NO;" из функции setPaused. Таким образом, поведение SpriteKit по умолчанию может делать все, что ему нравится, но игра будет оставаться приостановленной до тех пор, пока мы хотим.

licensed under cc by-sa 3.0 with attribution.