Ahora hablaremos de las pausas y reinicio del juego, que es tan importante en los juegos, el libro de frente nos advierte no usar thread.suspend() y resume(). Ya que están depreciadas por las mismas razones que thread.Stop()-Suspend(), ya que el programa quizás se quede usando un recurso y no será liberado hasta que el hilo funcione de nuevo.
La documentación de java recomienda usar Wait() y notify() para implementar estas funciones, ya que los hilos que manejan los eventos serán capaces de responder a la actividad de pantalla.
Lo que viene es la función pauseGame():
// variable global private boolean isPaused = false; - - public void run() /* actualiza, renderiza y duerme constantemente*/ { /* Reptidamente: actualiza,renderiza, duerme, */ long beforeTime, afterTime, timeDiff, sleepTime; long excess = 0L; beforeTime = System.currentTimeMillis(); running = true; while(running) { try { if (isPaused) {// si pausa es true synchronized(this) { while (isPaused && running) wait();//espera } } } // of try block catch (InterruptedException e){} gameUpdate(); // Actualiza el estado del juego gameUpdate(); // Vuelve a actualizar el estado del juego gameRender(); // renderiza en un buffer
ispaused es detectada en run() y se hace un wait() para suspender la animación.
Ahora el hilo debe ser restaurado o destruido y para eso utilizamos resumeGame() o stopGame(), los cuales llaman a notify(). Estas funciones deben estar sincronizadas para que le hilo de animación no quede suspendida indefinidamente
public synchronized void resumeGame() { isPaused = false; // we do not do this notify(); } public synchronized void stopGame() { running = false; // we do not do this notify(); }
El libro ahora nos propone otra forma de las cosas, la razón que da es que el wait() en run() hace parar todo el hilo de animación y a veces no queremos eso, por ejemplo en los juegos en red, el juego debe estar constantemente chequeando los sockets en caso haya mensajes entre los jugadores.
La propuesta sigue usando el booleano isPaused() usado en pauseGame()
// variable global private boolean isPaused = false; - - - public void pauseGame(){ isPaused = true; }
La diferencia es que isPaused no es monitoreada en run() solo en las funciones testPress() y gameUpdate()
private void gameUpdate() { if (!isPaused && !gameOver) // actualiza el estado del juego ... } private void testPress(int x, int y) // es (x,y) importante para el juego? { if (!isPaused && !gameOver) { // hace algo } }
De esta manera la función que escucha el teclado sigue funcionando y se puede salir del juego aun en pausa. En resumeGame se convierte el boolean isPaused a falso
public void resumeGame() { isPaused = false; }
Las situaciones donde la pausa y el restaurar son usados varían dependiendo el tipo de programa en java que los use, por ejemplo los applets, la animación debería pausar cuando paran el applet y restaurar cuando lo resetean desde el navegador, un parada también podría ocurrir cuando una persona deja la pagina para ver otra y debe restaurar cuando el usuario regresa a la pagina.
En las aplicaciones de pantalla completa, la pausa y el resumen son controlados por botones en el canvas, ya que no hay una barra de titulo y la barra de tareas la esconde el S.O.
Buena Suerte!