首页 > 解决方案 > 相对于javafx中的视图移动相机?

问题描述

我的场景中有一个摄像机,我目前正在使用 WASD 在 xy 和 z 轴上移动。但是,我希望它根据它所面临的方向移动。为了更好地说明我的意思,我使用程序搅拌器中的片段来演示这个想法。

图 1

在图 1 中,这很容易。向前移动只会在 x(红色)轴上移动,向两侧移动将在 y(绿色)轴上移动。当相机旋转时会出现问题,从而改变它相对于轴的位置,如顶视图中的图像 2 所示:

图 2

如果我现在尝试向前移动(红色箭头的方向),我需要移动以适应旋转,并调整 x 和 y 坐标,以便相机从其视角向前移动。

有没有办法做到这一点?我已经尝试了许多涉及正弦和余弦的计算,以及很多谷歌搜索,但它没有导致任何结果。谷歌大多使用 OpenGL 显示未解决的问题或解决方案,而我的数学方程式只是吐出不正确的结果。

我希望我清楚地解释了这个问题,如果没有,我很乐意提供更多信息。感谢您的时间!

标签: javafxcamera

解决方案


我知道我迟到了 3 个月,但我想我知道你的意思。

在 JavaFX 中,您有一个名为 world 的组(除了相机之外的所有 3d)。如果要将相机向左旋转(例如围绕 y 轴),则不要触摸相机而是触摸世界并围绕 y 轴旋转它。

老实说,我不是 100% 理解它为什么有效,但它对我有用(我正在开发一款游戏,所以我必须经历它)。

我希望这能回答你的问题:D

编辑 1:示例代码

package FXTesting;

import javafx.application.Application;
import javafx.scene.Camera;
import javafx.scene.Group;
import javafx.scene.PerspectiveCamera;
import javafx.scene.Scene;
import javafx.scene.input.KeyEvent;
import javafx.scene.shape.Box;
import javafx.scene.transform.Rotate;
import javafx.scene.transform.Translate;
import javafx.stage.Stage;

public class Main extends Application {

    public static int SIZEFACTOR = 100;

    @Override
    public void start(Stage primaryStage) throws Exception {
        Group world = createEnvironment();

        Scene scene = new Scene(world);
        primaryStage.setScene(scene);
        primaryStage.setWidth(16 * SIZEFACTOR);
        primaryStage.setHeight(9 * SIZEFACTOR);

        Camera camera = new PerspectiveCamera();
        camera.setFarClip(2000);
        camera.setNearClip(1);

        scene.setCamera(camera);

        Rotate worldRotX = new Rotate(0, Rotate.X_AXIS);
        Rotate worldRotY = new Rotate(0, Rotate.Y_AXIS);

        Translate  worldTransX = new Translate();

        world.getTransforms().addAll(worldRotY, worldRotX);

        primaryStage.addEventHandler(KeyEvent.KEY_PRESSED, event -> {
            switch(event.getCode()){
                case LEFT:
                    worldRotY.setAngle(worldRotY.getAngle() + 10);
                    break;
                case RIGHT:
                    worldRotY.setAngle(worldRotY.getAngle() - 10);
                    break;
                case UP:
                    worldRotX.setAngle(worldRotX.getAngle() + 10);
                    break;
                case DOWN:
                    worldRotX.setAngle(worldRotX.getAngle() - 10);
                case W: //w/s is for z
                    world.setTranslateZ(world.getTranslateZ() + 10);
                    break;
                case S:
                    world.setTranslateZ(world.getTranslateZ() - 10);
                    break;
                case A:// a/d is x axis
                    world.setTranslateX(world.getTranslateX() + 10);
                    break;
                case D:
                    world.setTranslateX(world.getTranslateX() - 10);
                    break;
                case SHIFT:// shift/contr is for y axis
                    world.setTranslateY(world.getTranslateY() + 10);
                    break;
                case CONTROL:
                    world.setTranslateY(world.getTranslateY() - 10);
                    break;

            }
        });

        primaryStage.show();
    }

    private Group createEnvironment(){
        Group group = new Group();

        Box ground = new Box();
        ground.setHeight(10);
        ground.setWidth(1000);
        ground.setDepth(1000);

        ground.setTranslateX(-500);
        ground.setTranslateZ(-500);


        Box box = new Box(100,100,100);
        box.setTranslateY(10);

        group.getChildren().addAll(ground, box);

        return group;
    }

    public static void main(String... args){
        launch(args);
    }
}

推荐阅读