Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

235
Views
JavaFX AnimationTimer no se detiene correctamente

Entonces, estoy creando el juego de la serpiente usando JavaFX y parece que no puedo hacer que el juego se detenga correctamente, es decir, se detiene ocasionalmente y otras veces, el juego simplemente ignora la pausa. Entonces, básicamente tengo una clase Main donde inicializo todos los componentes de la GUI, y también actúa como controlador para la aplicación javafx.

Tengo un Button llamado gameControl que inicia/pausa el juego, una Boolean pause variable que realiza un seguimiento de los estados del juego (nuevo/en pausa/en ejecución) y los métodos startGame , pauseGame .

El manejador de EventHandler del botón gameControl es el siguiente:

 gameControl.setOnClicked(event->{ if(paused == null) startGame(); //new game else if(paused) continueGame(); //for paused game else pauseGame(); //for running game });

La función startGame se parece a esto:

 void startGame(){ paused = false; Snake snake = new Snake(); //the snake sprite //following gameLoop controls the animation of the snake gameLoop = new AnimationTimer(){ @Override public void handle(long now){ drawSnake(); //draws the snake on the game snake.move(); //move snake ahead //following code is for slowing down the gameLoop renders to make it easier to play Task<Void> sleeper = new Task<>(){ @Override protected Void call() throws Exception { gameLoop.stop(); Thread.sleep(30); gameLoop.start(); return null; } }; new Thread(sleeper).start(); //force garbage collection or else throws a bunch of exceptions after a while of running. //not sure of the cause... System.gc(); } }; gameLoop.start(); }

AnimationTimer gameLoop son variables de la clase para permitir llamar desde otras funciones.

Y la función pauseGame :

 void pauseGame() { paused = true; gameLoop.stop(); }

Entonces, como dije antes, el juego no se detiene cada vez que presiono el botón gameControl , y sospecho que se debe a Thread.sleep(30); línea dentro de la Task del gameLoop . Dicho esto, todavía no estoy completamente seguro y no tengo idea de cómo solucionarlo. Cualquier ayuda sería apreciada.

over 4 years ago · Santiago Trujillo
2 answers
Answer question

0

¿Qué tipo es 'en pausa'? Verifica que sea nulo, pero luego lo trata como un booleano. No puedo entender por qué sería un contenedor de objeto booleano 'B' grande en lugar del tipo booleano primitivo.

Este:

 //following code is for slowing down the gameLoop renders to make it easier to play Task<Void> sleeper = new Task<>(){ @Override protected Void call() throws Exception { gameLoop.stop(); Thread.sleep(30); gameLoop.start(); return null; } };

Es una manera absolutamente horrible de acelerar la velocidad. Deje que se ejecute el ciclo de su juego, verifique el tiempo en cada ciclo para ver si ha transcurrido suficiente tiempo como para actualizar las cosas. Su temporizador de animación impulsará el juego. No desea pausar el subproceso de la plataforma principal, no desea pausar ningún subproceso de trabajo que esté manejando tareas. Si está programando tareas, prográmelas para que se ejecuten en los intervalos que desee; no acelere el hilo en el método call().

Lo que realmente quieres es algo como esto:

 //following gameLoop controls the animation of the snake gameLoop = new AnimationTimer(){ @Override public void handle(long now){ if ((now - lastTime) > updateIterval) { drawSnake(); //draws the snake on the game snake.move(); //move snake ahead lastTime = now; }

Incluso podría hacer un bucle para "ponerse al día" en caso de que el temporizador de animación se retrase por algún motivo:

 while ((now - lastTime) > updateIterval) { drawSnake(); //draws the snake on the game snake.move(); //move snake ahead lastTime += updateIterval; }
over 4 years ago · Santiago Trujillo Report

0

Tu intuición de que Thread.sleep(30); puede estar causando un problema está en el camino correcto. Un usuario puede hacer clic en el botón que llama a pauseGame , establecer pausado en verdadero y decirle al bucle de juego que se detenga. Si el nuevo subproceso durmiente se inicia y está durmiendo en ese momento, llamará a start() en el bucle de juego cuando se despierte.

Una opción puede ser simplemente verificar el valor de paused en la tarea durmiente para determinar si debe iniciar el bucle de juego.

 Task<Void> sleeper = new Task<>(){ @Override protected Void call() throws Exception { gameLoop.stop(); Thread.sleep(30); if (!paused) { gameLoop.start(); } return null; } };

Dado que el valor en pausa se establece y se lee desde varios subprocesos, recomendaría agregar un mecanismo para asegurarse de que no obtenga un comportamiento no determinista. Cambiar el booleano por un AtomicBoolean es una opción sencilla para garantizar la coherencia.

over 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!