如何在spritekit中有效地暂停游戏?

时间:2023-01-22 23:45:03

This seems like such a basic concept but there is really no good answer.

这似乎是一个基本概念,但实际上没有好的答案。

I currently have a pretty basic setup, in my game's scene, I have an enum gameState which is currently either inGame or gamePaused.

我目前有一个非常基本的设置,在我的游戏场景中,我有一个enum gameState,目前正在游戏或gamePaused。

I have my button set up, and I have it so pressing simply toggles gameState.

我已经设置了我的按钮,而且我只需要按下即可切换游戏状态。

Then, to make it work, I have two separate update methods: One for when gamePaused, one for when inGame.

然后,为了使它工作,我有两个单独的更新方法:一个用于gamePaused,一个用于inGame。

This works for 95% of my game, as the updates in my game can be pretty readily started and stopped without any issues. There are some issues I cannot tackle though.

这适用于我游戏的95%,因为我的游戏中的更新可以很容易地启动和停止而没有任何问题。有些问题我无法解决。

First and foremost are actions. I use SKActions for a bit of my project (some movement, scaling, fading...) and this method does NOT pause them. This can be catastrophic in certain points. Secondly, this doesn't handle particles, physics, and a few other things that are not directly associated to my update methods.

首要的是行动。我使用SKActions进行了一些项目(一些移动,缩放,渐变......),这种方法不会暂停它们。在某些方面,这可能是灾难性的。其次,这不处理粒子,物理和其他一些与我的更新方法没有直接关联的东西。

The only clue I have is self.view.paused = YES, but that isn't going to work either.

我唯一的线索是self.view.paused = YES,但这也不会起作用。

First off, this DOES fix my actions, particles, and physics problem... kinda. But This question suggests that SKActions aren't actually PAUSED by this, but actually STOPPED completely. Is this true? If it is, then it won't work smoothly either because my actions are thrown out of whack.

首先,这可以解决我的行为,粒子和物理问题...有点儿。但是这个问题表明SKActions实际上并没有被这个暂停,但实际上完全停止了。这是真的?如果是,那么它也不会顺利运作,因为我的行为被抛弃了。

Also, pausing the view seems to do what it says: stop everything. EVERYTHING. Newbie question here, but how am I supposed to get any code to run at that point? It's all cut off. Is this where I need subViews? I have never used a subView yet, but it sounds like its what I want in this case.

此外,暂停视图似乎做了它所说的:停止一切。一切。新手问题在这里,但我怎么能得到任何代码运行在那一点?一切都被切断了。这是我需要subViews的地方吗?我还没有使用过subView,但在这种情况下听起来就像我想要的那样。

Simply put, there are a lot of unanswered questions for me, and I don't know how to proceed. I'm hoping there's some 'standard procedure' for pausing in Sprite Kit, but with pausing the view halting actions I truly have no idea where to proceed.

简单地说,对我来说有很多未解决的问题,我不知道如何继续。我希望在Sprite Kit中暂停一些“标准程序”,但是暂停视图暂停操作我真的不知道从哪里开始。

Should I move away from using actions? Is my idea of a pause subView sound?

我应该放弃使用行动吗?我的暂停subView声音是什么意思?

I don't want to babble, all I want to know is how you go about pausing in your average Sprite Kit project. Additional info provided upon request.

我不想喋喋不休,我想知道的是你如何在你的平均Sprite Kit项目中暂停。根据要求提供其他信息。

6 个解决方案

#1


13  

Pausing a node will pause (not stop) the node's actions, and i suppose pause will also be applied to all children of the paused node in the same way. All other unpaused nodes will continue to run their actions to completion.

暂停节点将暂停(不停止)节点的操作,我想暂停也将以相同的方式应用于暂停节点的所有子节点。所有其他未启动的节点将继续运行其操作以完成。

You should have a "game layer" node with all game nodes in them that you want to pause, and then just pause that "game layer" node. Then have a "pause game menu" node where you add all the pause menu stuff you need which will continue to function normally even if the game layer is paused.

您应该有一个“游戏层”节点,其中包含您要暂停的所有游戏节点,然后暂停该“游戏层”节点。然后有一个“暂停游戏菜单”节点,您可以在其中添加所需的所有暂停菜单内容,即使游戏层暂停,这些内容也将继续正常运行。

Be very sure you do not use performSelector or NSTimer or GCD or any other scheduling methods besides actions or the scene's update: method because those will not adhere to a node's paused state.

除了操作或场景的更新:方法之外,请确保不使用performSelector或NSTimer或GCD或任何其他调度方法,因为这些方法不会遵循节点的暂停状态。

Pausing the view effectively freezes everything in it, pausing the scene according to some will not pause the update: calls - but I have not verified this myself. If this were the case you can always check inside the update method whether a given node that you send a message to is paused and if so, decide not to send certain messages to that node.

暂停视图可以有效地冻结其中的所有内容,根据某些内容暂停场景不会暂停更新:调用 - 但我自己也没有验证过。如果是这种情况,您可以随时在update方法中检查您发送消息的给定节点是否暂停,如果是,则决定不向该节点发送某些消息。

#2


2  

I just called a map function on all children of the scene and set the paused property to true

我刚刚在场景的所有子节点上调用了一个map函数,并将paused属性设置为true

self.children.map{($0 as SKNode).paused = false}

By setting it to true you can easily undo the freeze.

通过将其设置为true,您可以轻松撤消冻结。

EDIT: Better use a for-loop to iterate over the children.

编辑:更好地使用for循环迭代孩子。

for node in self.children as [SKNode] {
    node.paused = false
}

#3


1  

I can tell you what I did in my game:

我可以告诉你我在游戏中做了些什么:

  1. Pause the SKView on -applicationWillResignActive: (or equivalent, using NSNotifications),

    在-applicationWillResignActive上暂停SKView :(或等效,使用NSNotifications),

  2. Un-pause the SKView on -applicationDidBecomeActive: (or equivalent, using NSNotifications),

    在-applicationDidBecomeActive上取消暂停SKView :(或等效,使用NSNotifications),

For the actual game scene only, I set a boolean flag _isPaused when resigning active, and if it is true I just skip the -update: method (frame updates). (I also show the "paused" menu when the user resumes the app).

对于实际的游戏场景,我在重新激活活动时设置了一个布尔标志_isPaused,如果是真的,我只是跳过-update:方法(帧更新)。 (当用户恢复应用程序时,我也会显示“暂停”菜单)。

...But my game is a simple puzzle game, and there's no long actions that should continue past the pause/resume. I can not confirm right now that all actions are aborted, but I think it's not the case.

...但我的游戏是一个简单的益智游戏,并且没有长时间的动作应该继续暂停/恢复。我现在无法确认所有行动都已中止,但我认为情况并非如此。

#4


0  

I also used self.children.map{($0 as SKNode).paused = false} and it does work if you create a var layer of type SKSpriteNode and add it on top of the scene. But I also have an NSTimer I'm using to spawn sprites on the scene. Everything currently on the scene is paused, but sprites keep appearing and moving across the screen. It is not pausing the spawning.

我还使用了self.children.map {($ 0 as SKNode).paused = false}如果你创建一个SKSpriteNode类型的var层并将其添加到场景顶部,它确实有效。但是我也有一个NSTimer,我用来在场景中产生精灵。当前在场的所有内容都会暂停,但精灵会不断出现并在屏幕上移动。它不会暂停产卵。

I tried pausing the NSTimer when I call the above code by setting repeats to false, then setting it to true when I remove the layer but it doesn't work. I also tried self.scene?.view?.paused = true but that freezes everything and the layer I create does not even appear onscreen.

当我通过将repeat重复设置为false来调用上面的代码时尝试暂停NSTimer,然后在删除图层时将其设置为true但它不起作用。我也试过self.scene?.view?.paused = true但是冻结了一切,我创建的图层甚至都没有出现在屏幕上。

#5


0  

You need to set the delegate for the View!

您需要为View设置委托!

func PauseGame(){
   self.scene.view.paused = true
}

fun playGame(){
   self.scene.pause = false
}

#6


0  

This function is work perfectly if you are not using the NSTimer to call a function. If you use NSTimer your view will pause perfectly but when you play the game again by play game functionality you see that all the functions that use the NSTimer function that runs in the back end and your screen full with your sprite-kits. So when you use NSTimer in the function you have to first pause the NSTimer functions also after that this function work perfectly.

如果您不使用NSTimer来调用函数,则此函数可以正常工作。如果您使用NSTimer,您的视图将完全暂停,但是当您通过游戏功能再次玩游戏时,您会看到所有使用NSTimer功能的功能在后端运行,而您的屏幕则使用精灵套件。因此,当您在函数中使用NSTimer时,您必须先暂停NSTimer函数,然后此函数才能正常工作。

//For Pause
func pauseGame() {
    scene?.view?.paused = true
}

//For play.
func playGame() { 
  scene?.view?.paused = false
}

#1


13  

Pausing a node will pause (not stop) the node's actions, and i suppose pause will also be applied to all children of the paused node in the same way. All other unpaused nodes will continue to run their actions to completion.

暂停节点将暂停(不停止)节点的操作,我想暂停也将以相同的方式应用于暂停节点的所有子节点。所有其他未启动的节点将继续运行其操作以完成。

You should have a "game layer" node with all game nodes in them that you want to pause, and then just pause that "game layer" node. Then have a "pause game menu" node where you add all the pause menu stuff you need which will continue to function normally even if the game layer is paused.

您应该有一个“游戏层”节点,其中包含您要暂停的所有游戏节点,然后暂停该“游戏层”节点。然后有一个“暂停游戏菜单”节点,您可以在其中添加所需的所有暂停菜单内容,即使游戏层暂停,这些内容也将继续正常运行。

Be very sure you do not use performSelector or NSTimer or GCD or any other scheduling methods besides actions or the scene's update: method because those will not adhere to a node's paused state.

除了操作或场景的更新:方法之外,请确保不使用performSelector或NSTimer或GCD或任何其他调度方法,因为这些方法不会遵循节点的暂停状态。

Pausing the view effectively freezes everything in it, pausing the scene according to some will not pause the update: calls - but I have not verified this myself. If this were the case you can always check inside the update method whether a given node that you send a message to is paused and if so, decide not to send certain messages to that node.

暂停视图可以有效地冻结其中的所有内容,根据某些内容暂停场景不会暂停更新:调用 - 但我自己也没有验证过。如果是这种情况,您可以随时在update方法中检查您发送消息的给定节点是否暂停,如果是,则决定不向该节点发送某些消息。

#2


2  

I just called a map function on all children of the scene and set the paused property to true

我刚刚在场景的所有子节点上调用了一个map函数,并将paused属性设置为true

self.children.map{($0 as SKNode).paused = false}

By setting it to true you can easily undo the freeze.

通过将其设置为true,您可以轻松撤消冻结。

EDIT: Better use a for-loop to iterate over the children.

编辑:更好地使用for循环迭代孩子。

for node in self.children as [SKNode] {
    node.paused = false
}

#3


1  

I can tell you what I did in my game:

我可以告诉你我在游戏中做了些什么:

  1. Pause the SKView on -applicationWillResignActive: (or equivalent, using NSNotifications),

    在-applicationWillResignActive上暂停SKView :(或等效,使用NSNotifications),

  2. Un-pause the SKView on -applicationDidBecomeActive: (or equivalent, using NSNotifications),

    在-applicationDidBecomeActive上取消暂停SKView :(或等效,使用NSNotifications),

For the actual game scene only, I set a boolean flag _isPaused when resigning active, and if it is true I just skip the -update: method (frame updates). (I also show the "paused" menu when the user resumes the app).

对于实际的游戏场景,我在重新激活活动时设置了一个布尔标志_isPaused,如果是真的,我只是跳过-update:方法(帧更新)。 (当用户恢复应用程序时,我也会显示“暂停”菜单)。

...But my game is a simple puzzle game, and there's no long actions that should continue past the pause/resume. I can not confirm right now that all actions are aborted, but I think it's not the case.

...但我的游戏是一个简单的益智游戏,并且没有长时间的动作应该继续暂停/恢复。我现在无法确认所有行动都已中止,但我认为情况并非如此。

#4


0  

I also used self.children.map{($0 as SKNode).paused = false} and it does work if you create a var layer of type SKSpriteNode and add it on top of the scene. But I also have an NSTimer I'm using to spawn sprites on the scene. Everything currently on the scene is paused, but sprites keep appearing and moving across the screen. It is not pausing the spawning.

我还使用了self.children.map {($ 0 as SKNode).paused = false}如果你创建一个SKSpriteNode类型的var层并将其添加到场景顶部,它确实有效。但是我也有一个NSTimer,我用来在场景中产生精灵。当前在场的所有内容都会暂停,但精灵会不断出现并在屏幕上移动。它不会暂停产卵。

I tried pausing the NSTimer when I call the above code by setting repeats to false, then setting it to true when I remove the layer but it doesn't work. I also tried self.scene?.view?.paused = true but that freezes everything and the layer I create does not even appear onscreen.

当我通过将repeat重复设置为false来调用上面的代码时尝试暂停NSTimer,然后在删除图层时将其设置为true但它不起作用。我也试过self.scene?.view?.paused = true但是冻结了一切,我创建的图层甚至都没有出现在屏幕上。

#5


0  

You need to set the delegate for the View!

您需要为View设置委托!

func PauseGame(){
   self.scene.view.paused = true
}

fun playGame(){
   self.scene.pause = false
}

#6


0  

This function is work perfectly if you are not using the NSTimer to call a function. If you use NSTimer your view will pause perfectly but when you play the game again by play game functionality you see that all the functions that use the NSTimer function that runs in the back end and your screen full with your sprite-kits. So when you use NSTimer in the function you have to first pause the NSTimer functions also after that this function work perfectly.

如果您不使用NSTimer来调用函数,则此函数可以正常工作。如果您使用NSTimer,您的视图将完全暂停,但是当您通过游戏功能再次玩游戏时,您会看到所有使用NSTimer功能的功能在后端运行,而您的屏幕则使用精灵套件。因此,当您在函数中使用NSTimer时,您必须先暂停NSTimer函数,然后此函数才能正常工作。

//For Pause
func pauseGame() {
    scene?.view?.paused = true
}

//For play.
func playGame() { 
  scene?.view?.paused = false
}