Autor Tema: Pausas (delay) en Java usando Thread.sleep para detener la ejecución un tiempo  (Leído 13690 veces)

Kabuto

  • Moderador Global
  • Experto
  • *******
  • Mensajes: 988
    • Ver Perfil
Hola a todos,

vereis, a modo de práctica, me he propuesto hacer un especie de jueguecito de rol por turnos en Java, donde desplazo a un personaje por un tablero y puedes encontrar muros, agujeros, cofres y, por supuesto,  enemigos.
No es nada serio, el motivo es más bien practicar y aprender nuevas cosas de la libreria Swing y tal...aunque obviamente para hacer juegos hay otras herramientas más adecuadas.

Voy bastante avanzado y seguramente más adelante iré pidiendo cierta ayuda. Pero ahora mismo tengo un problemita de escasa importancia.

Cuando se inicia un combate por turnos, aparede un JDialog con imagenes del jugador y el enemigo, botones.. y abajo un JTextArea donde se va mostrando la información del proceso del combate: Quien ataca, que daños ha causado, si ha fallado el ataque.. etc...

Mi intención es que tras cada linea de información, que agrego al area de texto, haya una pequeña pausa temporal (un delay) hasta que ocurra la siguiente acción.

Lo he intentado con un pequeño método que he llamado delay(), al cual le paso un tiempo en milisegundos y uso el método Thread.sleep() para que se detenga la acción.

Código: [Seleccionar]
private void delay(long milis)
{
try {
Thread.sleep(milis);
} catch (InterruptedException e) {
e.printStackTrace();
}
}

Así, lo que hago es llamarlo varias veces en determinados momentos para pausar "la acción" del combate. Os pongo un método en donde lo llamo, a modo de ejemplo (es un método incompleto, aun en construcción..)

Citar
@Override
      public void actionPerformed(ActionEvent arg0) {
         pJugador.pBotones.ataque.setEnabled(false);
         pJugador.pBotones.huida.setEnabled(false);
         delay(1000l);
         pInfo.addTexto("\n\t************************\n");
         pInfo.addTexto(jugador.getNombre() + " ataca con " + jugador.getInventario()[0].getNombre());
         delay(1000l);
         int ataqueJugador = atacar(jugador);
         int defensaCPU = defender(CPU);
         int resultado = ataqueJugador - defensaCPU;
         if  (resultado <= 0)
         {
            pInfo.addTexto("Daños causados: 0");
            delay(1000l);
            pInfo.addTexto("¡¡Tu ataque ha fallado!!");
         }
         else
         {
            CPU.pierdeVida(resultado);
            pCPU.setVida(CPU.getVida());
            pInfo.addTexto("Daños causados: " + resultado);
            delay(1000l);
            if (ataqueJugador > jugador.getAtaque())
               pInfo.addTexto("¡¡Has causado daños críticos!!");
         }
         
         if (CPU.getVida() <= 0)
         {
            delay(1000l);
            pInfo.addTexto("Has derrotado a " + CPU.getNombre());
         }
         else
         {
            delay(1000l);
            pInfo.addTexto("Es el turno de " + CPU.getNombre());
            delay(250l);
            int ataqueCPU = atacar(CPU);
            int defensaJugador = defender(jugador);
            resultado = ataqueCPU - defensaJugador;
            if  (resultado <= 0)
            {
               pInfo.addTexto("Daños causados: 0");
               delay(500l);
               pInfo.addTexto("¡¡" + CPU.getNombre() + " ha fallado!!");
            }
            else
            {
               jugador.pierdeVida(resultado);
               pJugador.setVida(jugador.getVida());
               pInfo.addTexto("Daños causados: " + resultado);
               delay(500l);
               if (ataqueCPU > CPU.getAtaque())
                  pInfo.addTexto("¡¡Has recibido daños críticos!!");
            }
         }
         
         if (jugador.getVida() == 0)
         {
            delay(1000l);
            pInfo.addTexto("Has muerto. FIN DE LA PARTIDA");
         }
         else if (CPU.getVida() == 0)
         {
            delay(1000l);
            pInfo.addTexto("¡¡Enhorabuena!! Has derrotado a tu enemigo.");
         }
         else
         {
            pJugador.pBotones.ataque.setEnabled(true);
            pJugador.pBotones.huida.setEnabled(true);
         }
            
         
      }

Este es el método que se ejecuta cuando se pulsa el botón "Atacar" y como veis llamo a mi método delay() en varios sitios.
Pero no está funcionando como yo esperaba. Parece como si, a pesar de que lo llamo en distintos sitios, al comenzar el método se crea un pausa muy larga, como si se sumasen todos los delays en uno solo.... y tras esta "macropausa" sale de golpe todas las lineas de texto en el JTextArea.... cuando mi idea es que vayan saliendo poco a poco, con distintas pausas repartidas a lo largo de la ejecución del código.

Ni siquiera se percibe la desactivación de los botones, y posterior reactivación al final del método.
Como digo, se hace un "macrodelay" inicial y luego pum, se ejecuta todo el código seguido.

¿Cómo podría conseguir lo que quiero hacer...? si es que es posible....

Espero haberme explicado bien.... gracias  y un saludo.
« Última modificación: 21 de Octubre 2017, 18:33 por Ogramar »
NO respondo dudas por mensaje privado
Publicando vuestras dudas en el foro público conseguimos:
- Que más gente aporte respuestas mejores o complementarias.
- Que otras personas puedan aprender de vuestras dudas.

Mejor en PÚBLICO que en privado. Gracias

javi in the sky

  • Avanzado
  • ****
  • Mensajes: 393
    • Ver Perfil
Re:Pausas (delay) en Java
« Respuesta #1 en: 05 de Septiembre 2017, 18:23 »
Hola kabuto aquí hay un ejemplo con thread sleep que a lo mejor te ayuda https://www.aprenderaprogramar.com/foros/index.php?topic=1699.0

Saludos!

Kabuto

  • Moderador Global
  • Experto
  • *******
  • Mensajes: 988
    • Ver Perfil
Re:Pausas (delay) en Java
« Respuesta #2 en: 05 de Septiembre 2017, 19:03 »
Gracias!!

Luego miraré de hacer pruebas, pero no comprendo el por qué se expresan así estos sleep();

Código: [Seleccionar]
Thread.sleep(1*1000);
Thread.sleep((1/1)*1000);
Thread.sleep(1*800)

¿Por qué no ponerlos así?
Código: [Seleccionar]
Thread.sleep(1000);
Thread.sleep(1000);
Thread.sleep(800)

Los tiempos solicitados son los mismos, pero supongo que hay alguna razón para realizar esas multipliaciones que no alteran el tiempo solicitado.
A ver si alguien me lo puediera explicar...

Gracias de nuevo.  ;)
NO respondo dudas por mensaje privado
Publicando vuestras dudas en el foro público conseguimos:
- Que más gente aporte respuestas mejores o complementarias.
- Que otras personas puedan aprender de vuestras dudas.

Mejor en PÚBLICO que en privado. Gracias

Ogramar

  • Moderador Global
  • Experto
  • *******
  • Mensajes: 2660
    • Ver Perfil
Buenas, Thread.sleep(1*1000); surte el mismo efecto que Thread.sleep(1000); creo que no aquí no tiene ninguna finalidad que lo hayan escrito así (si acaso tratar de indicar que es un milisegundo mil veces, o sea, mil milisegundos) o al menos yo no le veo ninguna finalidad.

Salu2

 

Sobre la educación, sólo puedo decir que es el tema más importante en el que nosotros, como pueblo, debemos involucrarnos.

Abraham Lincoln (1808-1865) Presidente estadounidense.

aprenderaprogramar.com: Desde 2006 comprometidos con la didáctica y divulgación de la programación

Preguntas y respuestas

¿Cómo establecer o cambiar la imagen asociada (avatar) de usuario?
  1. Inicia sesión con tu nombre de usuario y contraseña.
  2. Pulsa en perfil --> perfil del foro
  3. Elige la imagen personalizada que quieras usar. Puedes escogerla de una galería de imágenes o subirla desde tu ordenador.
  4. En la parte final de la página pulsa el botón "cambiar perfil".