¿Cómo detener de forma efectiva un juego en Spritekit?

Esto parece ser un concepto tan básico pero realmente no hay una buena respuesta.

Actualmente tengo una configuration bastante básica, en la escena de mi juego, tengo un enum gameState que actualmente está en inGame o gamePaused .

Tengo mi button configurado, y lo tengo tan presionado simplemente alterna gameState .

Entonces, para que funcione, tengo dos methods de actualización separados: uno para cuando gamePaused , uno para when inGame .

Esto funciona para el 95% de mi juego, ya que las actualizaciones en mi juego pueden comenzar y detenerse fácilmente sin problemas. Sin embargo, hay algunos problemas que no puedo abordar.

Primero y principal son las acciones. Utilizo SKActions para un poco de mi proyecto (algún movimiento, escala, desvanecimiento …) y este método NO los detiene. Esto puede ser catastrófico en ciertos puntos. En segundo lugar, esto no trata las partículas, la física y algunas otras cosas que no están asociadas directamente con mis methods de actualización.

La única pista que tengo es self.view.paused = YES , pero eso tampoco va a funcionar.

Primero, esto arregla mis acciones, partículas y problema de física … un poco. Pero esta pregunta sugiere que SKActions realidad no son SKActions por esto, pero en realidad STOPPED por completo. ¿Es esto cierto? Si es así, entonces no funcionará bien, ya sea porque mis acciones son desechadas.

Además, pausar la vista parece hacer lo que dice: detener todo. TODO. Pregunta de novato aquí, pero ¿cómo se supone que debo get un código para ejecutar en ese momento? Todo está cortado. ¿Es aquí donde necesito subViews ? Nunca he usado una subView todavía, pero parece que es lo que quiero en este caso.

En pocas palabras, hay muchas preguntas sin respuesta para mí, y no sé cómo proceder. Espero que haya un "procedimiento estándar" para pausar en Sprite Kit , pero si pausas las acciones de detención de la vista, realmente no tengo idea de dónde proceder.

¿Debería alejarme de usar acciones? ¿Es mi idea de un sonido de subView pausa?

No quiero balbucear, todo lo que quiero saber es cómo haces una pausa en tu proyecto promedio de Sprite Kit . Información adicional proporcionada a pedido.

Pausar un nodo pausará (no detendrá) las acciones del nodo, y supongo que la pausa también se aplicará a todos los niños del nodo detenido del mismo modo. Todos los demás nodos sin pausa seguirán ejecutando sus acciones hasta su finalización.

Debería tener un nodo de "capa de juego" con todos los nodos del juego que desee pausar, y luego pausar ese nodo de "capa de juego". Luego, tenga un nodo de "menu de pausa del juego" donde agregue todas las cosas del menu de pausa que necesita, que continuarán funcionando normalmente incluso si la capa del juego está en pausa.

Asegúrese de no utilizar performSelector o NSTimer o GCD o cualquier otro método de progtwigción además de las acciones o la actualización de la escena: método porque esos no se adherirán al estado pausado de un nodo.

Pausar la vista efectivamente congela todo, pausando la escena de acuerdo con algunos no hará una pausa en la actualización: llamadas, pero no he verificado esto yo mismo. Si este fuera el caso, siempre puede verificar dentro del método de actualización si un nodo determinado al que envía un post está en pausa y, de ser así, decide no enviar ciertos posts a ese nodo.

Acabo de llamar a una function de map en todos los niños de la escena y establezco la propiedad pausada en verdadero

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

Al establecerlo como verdadero, puede deshacer fácilmente la congelación.

EDIT: Mejor use un bucle forzado para iterar sobre los niños.

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

Puedo decirte lo que hice en mi juego:

  1. Pause el SKView en SKView -applicationWillResignActive: (o equivalente, usando NSNotification s),

  2. SKView en SKView -applicationDidBecomeActive: (o equivalente, usando NSNotification s),

Solo para la escena real del juego, establezco un indicador boolean _isPaused cuando _isPaused activo, y si es cierto, simplemente salto el -update: method (frames updates). (También muestro el menu "pausado" cuando el usuario reanuda la aplicación).

… Pero mi juego es un juego de rompecabezas simple, y no hay acciones largas que deberían continuar más allá de la pausa / reanudar. No puedo confirmar ahora que todas las acciones se abortan, pero creo que no es el caso.

También utilicé self.children.map{($0 as SKNode).paused = false} y funciona si creas una capa var de tipo SKSpriteNode y la agrega a la parte superior de la escena. Pero también tengo un NSTimer que estoy usando para engendrar sprites en la escena. Todo lo que está en escena actualmente está en pausa, pero los sprites siguen apareciendo y avanzando por la pantalla. No se pausa el desove.

Intenté pausar el NSTimer cuando llamo al código anterior estableciendo repeticiones en falso, y luego configurándolo a verdadero cuando elimino la capa, pero no funciona. También probé self.scene?.view?.paused = true pero eso lo congela todo y la capa que creo no aparece en la pantalla.

¡Necesitas configurar el delegado para la Vista!

 func PauseGame(){ self.scene.view.paused = true } fun playGame(){ self.scene.pause = false } 

Esta function funciona perfectamente si no está utilizando el NSTimer para llamar a una function. Si usas NSTimer, tu vista se detendrá a la perfección, pero cuando vuelvas a jugar con la funcionalidad de juego, verás que todas las funciones que usan la function NSTimer que se ejecuta en el back-end y la pantalla completa con tus sprite-kits . Por lo tanto, cuando utiliza NSTimer en la function, primero debe pausar las funciones NSTimer también después de que esta function funcione perfectamente.

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