Java 使用场景生成器在画布上绘制
现在我正在玩JavaFX,我想做的是在已经用Scene Builder创建的画布上绘制某种动画。不幸的是,我无法在画布上获得任何东西,因为每当我使用GraphicsContext做一些事情时,都会出现一些异常 我对Java和JavaFX都很陌生,我一直在寻找解决这个问题的方法,但我就是无法解决它 循环似乎正在成功运行,因为我能够获得控件打印,但是任何与在Java 使用场景生成器在画布上绘制,java,javafx,scenebuilder,Java,Javafx,Scenebuilder,现在我正在玩JavaFX,我想做的是在已经用Scene Builder创建的画布上绘制某种动画。不幸的是,我无法在画布上获得任何东西,因为每当我使用GraphicsContext做一些事情时,都会出现一些异常 我对Java和JavaFX都很陌生,我一直在寻找解决这个问题的方法,但我就是无法解决它 循环似乎正在成功运行,因为我能够获得控件打印,但是任何与在gameCanvasCanvas上渲染图形相关的操作都会触发异常 错误:(例如,由于run()方法中的gc.setFill(Color.RED)
gameCanvas
Canvas上渲染图形相关的操作都会触发异常
错误:(例如,由于run()
方法中的gc.setFill(Color.RED)
,我得到了这些错误
Exception in thread "JavaFX Application Thread" java.lang.NullPointerException
at Game.lambda$0(Game.java:54)
at javafx.graphics/com.sun.scenario.animation.shared.TimelineClipCore.visitKeyFrame(Unknown Source)
at javafx.graphics/com.sun.scenario.animation.shared.TimelineClipCore.playTo(Unknown Source)
at javafx.graphics/javafx.animation.Timeline.doPlayTo(Unknown Source)
at javafx.graphics/javafx.animation.AnimationAccessorImpl.playTo(Unknown Source)
at javafx.graphics/com.sun.scenario.animation.shared.InfiniteClipEnvelope.timePulse(Unknown Source)
at javafx.graphics/javafx.animation.Animation.doTimePulse(Unknown Source)
at javafx.graphics/javafx.animation.Animation$1.lambda$timePulse$0(Unknown Source)
at java.base/java.security.AccessController.doPrivileged(Native Method)
at javafx.graphics/javafx.animation.Animation$1.timePulse(Unknown Source)
at javafx.graphics/com.sun.scenario.animation.AbstractMasterTimer.timePulseImpl(Unknown Source)
at javafx.graphics/com.sun.scenario.animation.AbstractMasterTimer$MainLoop.run(Unknown Source)
at javafx.graphics/com.sun.javafx.tk.quantum.QuantumToolkit.pulse(Unknown Source)
at javafx.graphics/com.sun.javafx.tk.quantum.QuantumToolkit.pulse(Unknown Source)
at javafx.graphics/com.sun.javafx.tk.quantum.QuantumToolkit.pulseFromQueue(Unknown Source)
at javafx.graphics/com.sun.javafx.tk.quantum.QuantumToolkit.lambda$runToolkit$11(Unknown Source)
at javafx.graphics/com.sun.glass.ui.InvokeLaterDispatcher$Future.run(Unknown Source)
at javafx.graphics/com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at javafx.graphics/com.sun.glass.ui.win.WinApplication.lambda$runLoop$3(Unknown Source)
at java.base/java.lang.Thread.run(Unknown Source)
我的代码:
import java.net.URL;
import java.util.ResourceBundle;
import javafx.animation.KeyFrame;
import javafx.animation.Timeline;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.canvas.Canvas;
import javafx.scene.canvas.GraphicsContext;
import javafx.scene.paint.Color;
import javafx.util.Duration;
import javafx.scene.shape.*;
public class Game implements Initializable, Runnable, ControlledScreen {
@FXML
public Canvas gameCanvas;
private GraphicsContext gc;
public enum difficulties {EASY, MEDIUM, HARD};
difficulties difficultyLevel;
int score = 0;
Snake snake;
Food food;
boolean running = true;
private Timeline gameloop = new Timeline();
@Override
public void setScreenParent(ScreensController screenPage) {
}
public void setLevelEasy() {
difficultyLevel = difficulties.EASY;
}
public void setLevelMedium() {
difficultyLevel = difficulties.MEDIUM;
}
public void setLevelHard() {
difficultyLevel = difficulties.HARD;
}
@Override
public void run() {
KeyFrame frame = new KeyFrame(Duration.seconds(0.2), event -> {
if (!running)
return;
System.out.println("The loop's running, yai!");
gc.setFill(Color.RED);
});
gameloop.getKeyFrames().add(frame);
gameloop.setCycleCount(Timeline.INDEFINITE);
gameloop.play();
}
@Override
public void initialize(URL location, ResourceBundle resources) {
gc = gameCanvas.getGraphicsContext2D();
}
}
提前感谢!您从哪里调用
run()
?在这里让控制器实现Runnable
似乎没有意义。@James\u D它是在新游戏对象实例化之后从另一个类调用的。您确定run()吗
正在实际控制器和FX应用程序线程上调用?@James\u D是的,游戏类是一个控制器,但我没有真正理解第二部分。请详细说明一下,好吗?“游戏类是控制器”没有真正的意义。控制器是一个特定的对象(通常由FXMLLoader
创建),不是类。@FXML
-注释字段仅在相关控制器中初始化。我询问了线程,因为通常实现Runnable
的目的是在后台线程上执行run()
方法。您在run()中的代码
必须在FX应用程序线程上执行,而不是在后台线程上执行。