2015-09-22 137 views
2

我正在用JavaFX 3D开发一款游戏,玩家沿着漫长的道路奔跑。他的方式有物品和障碍。重点是:现在,如果物体进入我的裁剪距离,它们就会从无处出现。因此,我想创建一些雾(或任何其他“隐藏”对象的初始化)如何在JavaFX 3D中创建雾?

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

+0

太宽泛的问题提供了一个明确的答案,但也许['FadeTransition'](http://docs.oracle.com/javase/8/javafx/api/javafx/animation/FadeTransition.html)会帮帮我。 –

回答

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); 
    } 
} 
1

典型的3D系统使用粒子系统要做到这一点,涉及的透明性,阿尔法波动,广告牌的纹理组合。相信与否雾,烟和火焰......粒子效果......实际上并不是3D,而是2D,定位,尺寸和着色以3D形式出现的图像。然后,它们的动画足够快,以便人类观看者无法辨别2D图像的细微差别。 JavaFX 3D的问题在于它不支持透明度“尚未”(它是非正式可用的)。此外,没有粒子类型的对象可以让你像James_D所建议的那样重叠形状和纹理,而无需手动管理相机的定位。 但是有希望...... F(X)yz项目提供了一个BillBoard类,它可以让你放置一个垂直于相机的图像。您可以使用计时器和一些Random.next()类型快速更新此图像使用James_D建议的方法为雾创建圆形创建。以这种方式使用BillBoard的一个例子是BillBoardBehaviourTest和CameraViewTest。性能在CameraViewTest中演示。 如果我是你,我会做的是在你的frustrum的后面-Z位置(对象进入场景的位置)设置一个大的粗糙的BillBoard对象,然后在屏幕外的窗格中设置一个定时器/随机循环生成器。然后使用CameraViewTest中的方法,快照屏幕窗格(其中包含圆圈),然后将该图像设置为BillBoard。您必须将SnapShot呼叫置于某个计时器上才能实现动画效果。 CameraViewTest演示了如何做到这一点。对用户的影响将是一堆移动模糊的小圈子。
便宜的雾!