使用鼠标在 JavaFX 中移动 3D 相机
3D Camera movement in JavaFX using mouse
我已经成功地使用鼠标拖动移动了相机。然而,问题是一旦我移动了相机并释放了鼠标按下,相机 returns 回到原点。
我希望相机保持在更改后的位置,这样当我再次使用鼠标移动相机时,它会从该位置移动到任意位置,而不是从原点移动。
package application;
import javafx.application.Application;
import javafx.stage.Stage;
import javafx.scene.Camera;
import javafx.scene.Group;
import javafx.scene.PerspectiveCamera;
import javafx.scene.Scene;
import javafx.scene.input.KeyEvent;
import javafx.scene.input.ScrollEvent;
import javafx.scene.layout.BorderPane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Sphere;
public class Main extends Application {
private static final int WIDTH = 900;
private static final int HEIGHT = 600;
//Tracks drag starting point for x and y
private double anchorX, anchorY;
@Override
public void start(Stage primaryStage) {
Sphere sphere = new Sphere(50);
Group group = new Group();
group.getChildren().add(sphere);
Camera camera = new PerspectiveCamera();
Scene scene = new Scene(group, WIDTH, HEIGHT);
scene.setFill(Color.SILVER);
scene.setCamera(camera);
sphere.setTranslateX(WIDTH / 2);
sphere.setTranslateY(HEIGHT / 2);
initMouseControl(scene, camera, primaryStage, sphere);
primaryStage.setTitle("Solar System Simulator");
primaryStage.setScene(scene);
primaryStage.show();
}
private void initMouseControl(Scene scene, Camera camera, Stage stage, Sphere sphere) {
scene.setOnMousePressed(event -> {
//Save start points
anchorX = event.getSceneX();
anchorY = event.getSceneY();
});
scene.setOnMouseDragged(event -> {
camera.setTranslateY(anchorY - event.getSceneY());
camera.setTranslateX(anchorX - event.getSceneX());
});
stage.addEventHandler(ScrollEvent.SCROLL, event -> {
sphere.setTranslateZ(sphere.getTranslateZ() + event.getDeltaY());
});
}
public static void main(String[] args) {
launch(args);
}
}
我尝试使用谷歌搜索来寻找解决方案,但在使用 javafx 进行相机移动时找不到太多信息
我不知道Google能在多大程度上帮助您解决逻辑问题。我没有进一步分析您的代码,但至少每次按下鼠标按钮时,您的相机位置都会按设计重置为零。您的更改不会累积。
首先,您的场景没有启用深度缓冲。这些构造函数在场景实例 Scene(Parent root,double width,double height,boolean depthBuffer)
和 Scene(Parent root,double width,double height,boolean depthBuffer,SceneAntialiasing antiAliasing)
中启用 3d 功能,两者都将 depthBufer 布尔值设置为 true。第二,如果你想翻译一个节点;翻译它得到它的当前坐标,然后添加新的坐标。这将避免重置坐标。我把拖动的结果除以10,因为它带来的值太高了
public class Main extends Application {
private static final int WIDTH = 900;
private static final int HEIGHT = 600;
//Tracks drag starting point for x and y
private double anchorX, anchorY;
@Override
public void start(Stage primaryStage) {
Sphere sphere = new Sphere(50);
Group group = new Group();
group.getChildren().add(sphere);
Camera camera = new PerspectiveCamera();
// for 3d Scene constructor must have zbuffer= true and SceneAntialiasing
Scene scene = new Scene(group, WIDTH, HEIGHT, true, SceneAntialiasing.BALANCED);
scene.setFill(Color.SILVER);
scene.setCamera(camera);
sphere.setTranslateX(WIDTH / 2);
sphere.setTranslateY(HEIGHT / 2);
initMouseControl(scene, camera, primaryStage, sphere);
primaryStage.setTitle("Solar System Simulator");
primaryStage.setScene(scene);
primaryStage.show();
}
private void initMouseControl(Scene scene, Camera camera, Stage stage, Sphere sphere) {
scene.setOnMousePressed(event -> {
//Save start points
anchorX = event.getSceneX();
anchorY = event.getSceneY();
});
// translating camera from its current coords pluss event
scene.setOnMouseDragged(event -> {
camera.setTranslateY(camera.getTranslateY() + ((anchorY - event.getSceneY()) / 10));
camera.setTranslateX(camera.getTranslateX() + ((anchorX - event.getSceneX()) / 10));
});
stage.addEventHandler(ScrollEvent.SCROLL, event -> {
sphere.setTranslateZ(sphere.getTranslateZ() + event.getDeltaY());
});
}
public static void main(String[] args) {
launch(args);
}
}
我已经成功地使用鼠标拖动移动了相机。然而,问题是一旦我移动了相机并释放了鼠标按下,相机 returns 回到原点。
我希望相机保持在更改后的位置,这样当我再次使用鼠标移动相机时,它会从该位置移动到任意位置,而不是从原点移动。
package application;
import javafx.application.Application;
import javafx.stage.Stage;
import javafx.scene.Camera;
import javafx.scene.Group;
import javafx.scene.PerspectiveCamera;
import javafx.scene.Scene;
import javafx.scene.input.KeyEvent;
import javafx.scene.input.ScrollEvent;
import javafx.scene.layout.BorderPane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Sphere;
public class Main extends Application {
private static final int WIDTH = 900;
private static final int HEIGHT = 600;
//Tracks drag starting point for x and y
private double anchorX, anchorY;
@Override
public void start(Stage primaryStage) {
Sphere sphere = new Sphere(50);
Group group = new Group();
group.getChildren().add(sphere);
Camera camera = new PerspectiveCamera();
Scene scene = new Scene(group, WIDTH, HEIGHT);
scene.setFill(Color.SILVER);
scene.setCamera(camera);
sphere.setTranslateX(WIDTH / 2);
sphere.setTranslateY(HEIGHT / 2);
initMouseControl(scene, camera, primaryStage, sphere);
primaryStage.setTitle("Solar System Simulator");
primaryStage.setScene(scene);
primaryStage.show();
}
private void initMouseControl(Scene scene, Camera camera, Stage stage, Sphere sphere) {
scene.setOnMousePressed(event -> {
//Save start points
anchorX = event.getSceneX();
anchorY = event.getSceneY();
});
scene.setOnMouseDragged(event -> {
camera.setTranslateY(anchorY - event.getSceneY());
camera.setTranslateX(anchorX - event.getSceneX());
});
stage.addEventHandler(ScrollEvent.SCROLL, event -> {
sphere.setTranslateZ(sphere.getTranslateZ() + event.getDeltaY());
});
}
public static void main(String[] args) {
launch(args);
}
}
我尝试使用谷歌搜索来寻找解决方案,但在使用 javafx 进行相机移动时找不到太多信息
我不知道Google能在多大程度上帮助您解决逻辑问题。我没有进一步分析您的代码,但至少每次按下鼠标按钮时,您的相机位置都会按设计重置为零。您的更改不会累积。
首先,您的场景没有启用深度缓冲。这些构造函数在场景实例 Scene(Parent root,double width,double height,boolean depthBuffer)
和 Scene(Parent root,double width,double height,boolean depthBuffer,SceneAntialiasing antiAliasing)
中启用 3d 功能,两者都将 depthBufer 布尔值设置为 true。第二,如果你想翻译一个节点;翻译它得到它的当前坐标,然后添加新的坐标。这将避免重置坐标。我把拖动的结果除以10,因为它带来的值太高了
public class Main extends Application {
private static final int WIDTH = 900;
private static final int HEIGHT = 600;
//Tracks drag starting point for x and y
private double anchorX, anchorY;
@Override
public void start(Stage primaryStage) {
Sphere sphere = new Sphere(50);
Group group = new Group();
group.getChildren().add(sphere);
Camera camera = new PerspectiveCamera();
// for 3d Scene constructor must have zbuffer= true and SceneAntialiasing
Scene scene = new Scene(group, WIDTH, HEIGHT, true, SceneAntialiasing.BALANCED);
scene.setFill(Color.SILVER);
scene.setCamera(camera);
sphere.setTranslateX(WIDTH / 2);
sphere.setTranslateY(HEIGHT / 2);
initMouseControl(scene, camera, primaryStage, sphere);
primaryStage.setTitle("Solar System Simulator");
primaryStage.setScene(scene);
primaryStage.show();
}
private void initMouseControl(Scene scene, Camera camera, Stage stage, Sphere sphere) {
scene.setOnMousePressed(event -> {
//Save start points
anchorX = event.getSceneX();
anchorY = event.getSceneY();
});
// translating camera from its current coords pluss event
scene.setOnMouseDragged(event -> {
camera.setTranslateY(camera.getTranslateY() + ((anchorY - event.getSceneY()) / 10));
camera.setTranslateX(camera.getTranslateX() + ((anchorX - event.getSceneX()) / 10));
});
stage.addEventHandler(ScrollEvent.SCROLL, event -> {
sphere.setTranslateZ(sphere.getTranslateZ() + event.getDeltaY());
});
}
public static void main(String[] args) {
launch(args);
}
}