盒子在另一个盒子下面移动,而不是穿过盒子移动 - JavaFX

tom*_*mmY 2 java javafx

我在 JavaFx 中所做的: https: //i.stack.imgur.com/OfOmO.gif

问题:盒子在盒子下面移动,而不是穿过盒子

应该发生什么: https: //i.stack.imgur.com/ZWgda.gif //在搅拌机中制作的预览

解释:当我按下向下键时,移动的立方体应该穿过另一个立方体

这是我的代码:

import javafx.application.Application;
import javafx.event.EventHandler;
import javafx.scene.*;
import javafx.scene.image.Image;
import javafx.scene.input.KeyEvent;
import javafx.scene.layout.AnchorPane;
import javafx.scene.paint.*;
import javafx.scene.shape.*;
import javafx.scene.transform.*;
import javafx.stage.Stage;

public class Main extends Application {
    @Override public void start(Stage stage) throws Exception {
        Group root3D = new Group();
        AnchorPane globalRoot = new AnchorPane();
        Scene scene = new Scene(globalRoot, 800, 400, true);
        PerspectiveCamera camera = new PerspectiveCamera(true);
        SubScene sub = new SubScene(root3D,800,400,false,SceneAntialiasing.BALANCED);
        
        camera.getTransforms().addAll(new Translate(),new Rotate(0, Rotate.Z_AXIS),new Rotate(0, Rotate.Y_AXIS), new Rotate(30, Rotate.X_AXIS), new Translate(0, 0, -50));
        sub.setCamera(camera);
        globalRoot.getChildren().add(sub);
        stage.setScene(scene);
        stage.show();
        
        PhongMaterial material = new PhongMaterial();
        Image image = new Image(getClass().getResourceAsStream("texture.png"));
        material.setDiffuseMap(image);
        material.setSpecularColor(Color.WHITE);
           
        Box box1 = new Box(5,5,5);
        box1.setMaterial(material);
        box1.setTranslateY(-5);
        root3D.getChildren().add(box1);
        
        Box box2 = new Box(5,5,5);
        box2.setMaterial(material);
        root3D.getChildren().add(box2);
        
        scene.setOnKeyPressed((EventHandler<? super KeyEvent>) new EventHandler <KeyEvent>() {
            @Override public void handle(KeyEvent arg0) {
                if (arg0.getCode().toString() == "DOWN") {
                        box1.setTranslateY(box1.getTranslateY()+1);
                    }}});
    }
    public static void main(String[] args) {
       launch(args);
     }
}
Run Code Online (Sandbox Code Playgroud)

这是纹理: https: //i.stack.imgur.com/NQjGN.png

请帮助

jew*_*sea 6

我认为您遇到的主要问题是没有为 3D 场景打开深度缓冲。

使用深度缓冲的修复示例:

import javafx.animation.*;
import javafx.application.Application;
import javafx.scene.*;
import javafx.scene.image.Image;
import javafx.scene.input.KeyCode;
import javafx.scene.paint.*;
import javafx.scene.shape.Box;
import javafx.scene.transform.*;
import javafx.stage.Stage;
import javafx.util.Duration;

public class Boxes extends Application {
    @Override
    public void start(Stage stage) throws Exception {
        Group group = new Group();
        Scene scene = new Scene(
                group,
                800, 400,
                true,
                SceneAntialiasing.BALANCED
        );
        PerspectiveCamera camera = new PerspectiveCamera(true);

        camera.getTransforms().addAll(
                new Translate(),
                new Rotate(0, Rotate.Z_AXIS),
                new Rotate(0, Rotate.Y_AXIS),
                new Rotate(30, Rotate.X_AXIS),
                new Translate(0, 0, -50)
        );
        scene.setCamera(camera);

        Image image = new Image(
                Boxes.class.getResourceAsStream(
                        "texture.png"
                )
        );

        PhongMaterial material1 = new PhongMaterial();
        material1.setDiffuseMap(image);

        PhongMaterial material2 = new PhongMaterial();
        material2.setDiffuseMap(image);
        material2.setDiffuseColor(Color.LIGHTBLUE);

        Box box1 = new Box(5, 5, 5);
        box1.setMaterial(material1);
        box1.setTranslateY(-5);
        group.getChildren().add(box1);

        Box box2 = new Box(5, 5, 5);
        box2.setMaterial(material2);
        group.getChildren().add(box2);
        box2.setTranslateZ(.01);

        TranslateTransition autoMover = new TranslateTransition(
                Duration.seconds(3),
                box1
        );
        autoMover.setFromY(-10);
        autoMover.setToY(10);
        autoMover.setAutoReverse(true);
        autoMover.setCycleCount(Animation.INDEFINITE);
        autoMover.play();

        scene.setOnKeyPressed(keyEvent -> {
            if (KeyCode.DOWN.equals(keyEvent.getCode())) {
                box1.setTranslateY(box1.getTranslateY() + 1);
            }

            if (KeyCode.UP.equals(keyEvent.getCode())) {
                box1.setTranslateY(box1.getTranslateY() - 1);
            }

            if (KeyCode.SPACE.equals(keyEvent.getCode())) {
                if (Animation.Status.RUNNING.equals(autoMover.getStatus())) {
                    autoMover.pause();
                } else {
                    autoMover.play();
                }
            }
        });

        stage.setScene(scene);
        stage.show();
    }

    public static void main(String[] args) {
        launch(args);
    }
}
Run Code Online (Sandbox Code Playgroud)

程序输出的 gif 动画。gif 编码丢失了一些保真度,因此该编码不能很好地反映实际的程序输出。因此,请尝试运行实际的程序,而不是仅仅观察 gif 编码。

盒子

它的作用是:

  1. 删除SubScene,因为本示例不需要它。
  2. 打开显示 3D 模型的场景的深度缓冲区(以前,3D 模型显示在关闭深度缓冲的子场景中)。
  3. 添加自动翻译动画功能。
  4. 将其中一个框设置为蓝色,以便更容易区分这些框。
  5. 为其中一个框设置一个小的 z 平移 ( .01),以确保一个框稍微落后于另一个框(这有助于平滑地解析深度缓冲区排序)。

如果您想了解深度缓冲在做什么,您可以阅读它:

深度缓冲区,也称为 z 缓冲区,是计算机图形学中使用的一种数据缓冲区,用于从特定角度表示 3D 空间中对象的深度信息。深度缓冲区有助于渲染场景,以确保正确的多边形正确遮挡其他多边形。