在JavaFX中,使用AnimationTimer来频繁更新Canvas节点似乎是合适的。也就是说,对于栅格化动画而不是矢量动画。我遇到了一个可能与VSync相关的问题。我的场景中有一个单独的画布,其中包含经常更改的2D数据(程序的其余部分使用节点完成)。当我这样做时,我倾向于在屏幕中间撕裂,这意味着AnimationTimer可能与显示器刷新率不同步。
此(简化)代码详细显示错误。请注意,我不知道它是否依赖于显示硬件,并且撕裂的确切位置可能会略有偏移。
import javafx.application.*;
import javafx.animation.*;
import javafx.scene.*;
import javafx.scene.canvas.*;
import javafx.stage.*;
import javafx.event.*;
import javafx.scene.input.*;
import javafx.scene.paint.*;
public class BugDemo extends Application {
public static void main(String...args) {
launch(args);
}
private Canvas background = new Canvas();
private Color bgColor = Color.rgb(0, 0, 0);
@Override
public void start(Stage primaryStage) throws Exception {
Group root = new Group();
startLoops(root);
Scene scene = new Scene(root);
initUserControls(scene);
background.widthProperty().bind(scene.widthProperty());
background.heightProperty().bind(scene.heightProperty());
root.getChildren().add(background);
primaryStage.setScene(scene);
primaryStage.setTitle("Bug Demo");
primaryStage.setMaximized(true);
primaryStage.show();
}
/**
* Initializes all running control managers for game field
* @param scene primary scene of game
*/
protected void initUserControls(Scene scene) {
EventHandler<MouseEvent> handler = new EventHandler<MouseEvent>(){
@Override
public void handle(MouseEvent event) {
bgColor = Color.rgb((int)((event.getX() / background.getWidth()) * 255),
(int)((event.getY() / background.getHeight()) * 255),
255);
}};
scene.getRoot().setOnMouseMoved(handler);
scene.getRoot().setOnMouseDragged(handler);
}
/**
* Starts all game loops, which will at the beginning of the simulation and often for the extent
* of it.
* @param parent Root node
*/
protected void startLoops(Parent parent) {
GraphicsContext gc = background.getGraphicsContext2D();
new AnimationTimer() {
@Override
public void handle(long now) {
drawBackground(gc);
}}.start();
}
protected void drawBackground(GraphicsContext gc) {
gc.setFill(bgColor);
gc.fillRect(0, 0, background.getWidth(), background.getHeight());
}
}
将鼠标光标移动到场景上将导致画布以背景颜色移动。当您移动鼠标时,您会注意到(可能是)框架中的撕裂。
我很可能只是在JavaFX上成为N00B,并且有一个非常友好的.sync() - 我应该在某个地方打电话的方法;但我还没有找到它。我发现提交给Oracle的bug看起来与类似。我的回答可能只是躲避使用Canvas和AnimationTimer进行动画制作。同样,即使目前还没有解决方案,如果有人有解决方法,我很乐意听到它!
谢谢!
答案 0 :(得分:0)
发现问题(感谢@VGR指出缺乏系统行为一致性)!似乎它根本不是Java;是马可。我专门将桌面窗口管理器切换到了Compiz;撕裂现在已经消失了。
显然,这根本不是Java中的错误;使用Marco是一种权衡。这是一种解脱!