2

我正在用 JavaFX 3D 开发一个游戏,玩家在其中跑了很长的路。他的路上有物品和障碍。关键是:现在,如果对象进入我的剪切距离,它们就会突然出现。因此我想创建某种雾(或任何其他“隐藏”对象初始化的东西)

问题是我找不到任何这样做的例子。我正在寻找一个示例代码/链接到源/任何其他建议。

4

2 回答 2

2

已经说过这是一个太宽泛的问题,并且必须有很多很多方法可以做到这一点,这是一种可能的实现。这是 2D,但很容易适应 3D 应用程序(我认为)。这个想法只是让一些浅灰色的圆圈在白色背景上四处飘荡,并对整个事物施加巨大的模糊。

然后,您可以让您的对象以它作为背景出现,并将它们从灰色淡入它们的真实颜色(或类似颜色)。圆圈的颜色和速度,以及模糊半径,可能需要一些调整......

import java.util.Random;

import javafx.animation.AnimationTimer;
import javafx.application.Application;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.effect.GaussianBlur;
import javafx.scene.layout.Pane;
import javafx.scene.layout.StackPane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;

public class FogExample extends Application {

    private static final int WIDTH = 600 ;
    private static final int HEIGHT = 600 ;


    @Override
    public void start(Stage primaryStage) {

        Fog fog = new Fog(WIDTH, HEIGHT);

        Scene scene = new Scene(new StackPane(fog.getView()), WIDTH, HEIGHT);
        primaryStage.setScene(scene);
        primaryStage.show();
    }


    public static class Fog {
        private final int width ;
        private final int height ;
        private final Pane fog ;
        private final Random RNG = new Random();

        public Fog(int width, int height) {
            this.width = width ;
            this.height = height ;
            this.fog = new Pane();
            Rectangle rect = new Rectangle(0, 0, width, height);
            rect.setFill(Color.rgb(0xe0, 0xe0, 0xe0));
            fog.getChildren().add(rect);

            for (int i = 0; i < 50; i++) {
                fog.getChildren().add(createFogElement());
            }

            fog.setEffect(new GaussianBlur((width + height) / 2.5));

        }

        private Circle createFogElement() {
            Circle circle = new Circle(RNG.nextInt(width - 50) + 25, RNG.nextInt(height - 50) + 25, 15 + RNG.nextInt(50));
            int shade = 0xcf + RNG.nextInt(0x20);
            circle.setFill(Color.rgb(shade, shade, shade));
            AnimationTimer anim = new AnimationTimer() {

                double xVel = RNG.nextDouble()*40 - 20 ;
                double yVel = RNG.nextDouble()*40 - 20 ;

                long lastUpdate = 0 ;

                @Override
                public void handle(long now) {
                    if (lastUpdate > 0) {
                        double elapsedSeconds = (now - lastUpdate) / 1_000_000_000.0 ;
                        double x = circle.getCenterX() ;
                        double y = circle.getCenterY() ;
                        if ( x + elapsedSeconds * xVel > width || x + elapsedSeconds * xVel < 0) {
                            xVel = - xVel ; 
                        }
                        if ( y + elapsedSeconds * yVel > height || y + elapsedSeconds * yVel < 0) {
                            yVel = - yVel ; 
                        }
                        circle.setCenterX(x + elapsedSeconds*xVel);
                        circle.setCenterY(y + elapsedSeconds * yVel);
                    }
                    lastUpdate = now ;
                }

            };
            anim.start();
            return circle ;
        }

        public Node getView() {
            return fog ;
        }
    }

    public static void main(String[] args) {
        launch(args);
    }
}
于 2015-09-22T21:07:28.800 回答
1

典型的 3D 系统使用粒子系统来执行此操作,该系统涉及透明度、alpha 波动和广告牌纹理的组合。信不信由你 雾、烟雾和火焰……粒子效果……实际上根本不是 3D,而是 2D 图像,它们已被定位、调整大小和着色以显示为 3D。然后它们的动画速度足够快,以至于人类观众无法分辨出 2D 图像的细微差别。JavaFX 3D 的问题是它“还”不支持透明度。(它是非官方的)。此外,没有粒子类型的对象可以让您按照 James_D 的建议覆盖形状和纹理,而无需手动管理相对于相机的定位。但是有希望...... F(X)yz 项目提供了一个 BillBoard 类,它允许您将图像垂直于相机放置。您可以使用 James_D 建议的方法使用 Timer 和一些 Random.next() 类型的 Circle 创建雾快速更新此图像。在 BillBoardBehaviourTest 和 CameraViewTest 中以这种方式使用 BillBoard 的示例。CameraViewTest 展示了性能。如果我是你,我会做的是在你的视锥体的后 -Z 位置(对象进入场景的位置)设置一个大的视锥体宽 BillBoard 对象,然后在屏幕外的窗格中设置一个定时器/随机圆生成器。然后使用 CameraViewTest 中的方法,对屏幕外窗格(有圆圈)进行快照,然后将该图像设置为 BillBoard。您必须在某个计时器本身上调用 SnapShot 才能实现动画效果。CameraViewTest 演示了如何做到这一点。
雾上便宜!

于 2015-09-23T12:11:00.957 回答