You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JavaFX 3D场景立方体移动时未穿透另一立方体而是从下方穿过问题求助

问题根因

代码的核心问题是创建3D SubScene时没有开启深度缓冲,导致JavaFX不会按照3D物体的实际空间位置判断渲染优先级,仅按节点添加到场景的顺序绘制,后添加的立方体永远覆盖在先添加的立方体上层,所以不会出现穿透效果。
另外代码中按键判断的写法不规范,也建议修改避免潜在问题。

修复方案

只需要修改两处代码即可:

  1. 创建SubScene时将第四个参数depthBuffer改为true
  2. 按键判断直接比对KeyCode枚举,不要转为字符串比对

修复后的完整代码

import javafx.application.Application;
import javafx.event.EventHandler;
import javafx.scene.*;
import javafx.scene.image.Image;
import javafx.scene.input.KeyCode;
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,true,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(new EventHandler <KeyEvent>() {
            @Override public void handle(KeyEvent arg0) {
                // 直接比对KeyCode枚举
                if (arg0.getCode() == KeyCode.DOWN) {
                        box1.setTranslateY(box1.getTranslateY()+1);
                    }}});
    }
    public static void main(String[] args) {
       launch(args);
     }
}

内容的提问来源于stack exchange,提问作者tommY

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.05 10:12:03