#java #javafx
Вопрос:
Что я сделал в JavaFx:https://i.stack.imgur.com/OfOmO.gif
проблема: коробка движется под коробкой, а не через коробку
Что должно произойти:
https://i.stack.imgur.com/ZWgda.gif //предварительный просмотр, сделанный в blender
объясните: Движущийся куб должен проходить через другой куб, когда я нажимаю клавишу вниз
И вот мой код:
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);
}
}
Вот текстура: https://i.stack.imgur.com/NQjGN.png
Помогите, пожалуйста
Комментарии:
1. Очень трудно объяснить, что должно было произойти. Но я все же попробовал.
2. Отключение буфера глубины в 3D-сцене, скорее всего, не то, что вам нужно.
Ответ №1:
Я думаю, что главная проблема, с которой вы столкнулись, заключается в том, что для вашей 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);
}
}
GIF-анимация вывода программы. Некоторая точность была потеряна в кодировке gif, так что эта кодировка на самом деле не очень хорошо отражает фактический вывод программы. Поэтому попробуйте запустить настоящую программу вместо того, чтобы просто наблюдать за кодировкой gif.
То, что он делает, это:
- Удалите
SubScene
, потому что это не требовалось для данного примера. - Включите буфер глубины для сцены, в которой отображаются 3D-модели (ранее 3D-модели отображались в подцене, в котором буферизация глубины была отключена).
- Добавьте возможность автоматического перевода анимации.
- Установите синий цвет для одной из коробок, чтобы их было легче различать.
- Установите небольшой перевод z (
.01
) для одного из ящиков, чтобы убедиться, что один ящик немного отстает от другого (что помогает в плавном разрешении упорядочения буфера глубины).
Вы можете прочитать о буферизации глубины, если хотите понять, что она делает:
Буфер глубины, также известный как z-буфер, представляет собой тип буфера данных, используемого в компьютерной графике для представления информации о глубине объектов в 3D-пространстве с определенной точки зрения. Буферы глубины помогают визуализировать сцену, чтобы убедиться, что правильные полигоны правильно перекрывают другие полигоны.