Так что я немного застрял на этом.У меня довольно простая игра, в которой вы перемещаете корабль по сетке с помощью клавиш со стрелками.
Я добавил еще один поток с каким-то монстром, который должен автоматически перемещаться по сетке.Из операторов печати видно, что поток работает, а монстр движется, однако местоположение изображения не обновляется.
Я нашел несколько похожих вопросов, и есть много рекомендаций по использованию Platfrom.runLater
.Но я не уверен, соответствует ли это моему конкретному случаю, и если да, то как его реализовать.
Вот что делает класс Monster, перемещая монстра вправо на одну позицию каждую секунду.Как я уже упоминал, я регистрирую текущее местоположение каждый раз, когда вызывается setX()
, поэтому я вижу, что местоположение обновляется.
import javafx.collections.ObservableList;
import javafx.scene.Node;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import java.awt.Point;
public class Monster implements Runnable {
private Point currentPoint;
private OceanMap map;
public Monster(int x, int y) {
this.currentPoint = new Point(x, y);
this.map = OceanMap.getInstance();
}
public Point getLocation() {
System.out.println(this.currentPoint.toString());
return this.currentPoint;
}
private void setNewLocation(Point newLocation) {
this.currentPoint = newLocation;
}
private void setY(int newY) {
this.currentPoint.y = newY;
this.setNewLocation(new Point(this.currentPoint.x, this.currentPoint.y));
}
private void setX(int newX) {
this.currentPoint.x = newX;
this.setNewLocation(new Point(this.currentPoint.x, this.currentPoint.y));
System.out.println(this.currentPoint.toString());
}
// public void addToPane() {
// System.out.println("this is called");
// iv.setX(this.currentPoint.x + 1 * 50);
// iv.setY(this.currentPoint.y * 50);
// obsrvList.add(iv);
// }
@Override
public void run() {
while (true) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
this.setX(this.currentPoint.x + 1);
}
}
}
А вот поток JavaFX.
/* Monster resources */
private Image monsterImage = new Image(getClass().getResource("monster.png").toExternalForm(), 50, 50, true, true);
private ImageView monsterImageView1 = new ImageView(monsterImage);
private Monster monster1;
private Thread monsterThread;
@Override
public void start(Stage oceanStage) throws Exception {
root = new AnchorPane();
scene = new Scene(root, scale * xDimensions, scale * yDimensions);
oceanStage.setScene(scene);
oceanStage.setTitle("Ocean Explorer");
/* Draw Grid */
for (int x = 0; x < xDimensions; x++) {
for (int y = 0; y < yDimensions; y++) {
Rectangle rect = new Rectangle(x * scale, y * scale, scale, scale);
rect.setStroke(Color.BLACK);
rect.setFill(Color.PALETURQUOISE);
root.getChildren().add(rect);
}
}
oceanStage.show();
monsterThread = new Thread(monster1);
monsterThread.start();
Platform.runLater(() -> {
monsterImageView1.setX(monster1.getLocation().x * scale);
monsterImageView1.setY(monster1.getLocation().y * scale);
root.getChildren().add(monsterImageView1);
});
startSailing();
}
Я могу предоставить больше кода, если это необходимо, это все, что я считал уместным на данный момент.
Итак, мой вопрос, как я могу обновить пользовательский интерфейс потока JavaFX из другого потока?