2017-06-06 82 views
1

需要使JavaFX中的球體隨時間「閃爍」,如淡入淡出。可能嗎?或者至少改變顏色的深淺。我設法讓它閃爍通過改變我現在用的是PhongMaterial的SelfIlluminationMap屬性,與此代碼在JavaFX中,隨着時間的推移,使3D對象照亮時間不同

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

public class JavaFXApplication15 extends Application { 

    Image im = new Image("bump.jpg"); 
    PhongMaterial ph = new PhongMaterial(Color.GREEN); 
    int nums = 0; 

    UpdateTimer timer; 

    private class UpdateTimer extends AnimationTimer { 

     int counter = 0; 

     @Override 
     public void handle(long now) { 
      if (counter == 20) { 
       update(); 
       counter = 0; 
      } 
      counter++; 

     } 
    } 

    private Parent createContent() throws Exception { 

     timer = new UpdateTimer(); 
     ph = new PhongMaterial(Color.YELLOW, null, null, null, im); 

     Box box = new Box(5, 5, 5); 
     box.setMaterial(ph); 

     // Create and position camera 
     PerspectiveCamera camera = new PerspectiveCamera(true); 
     camera.getTransforms().addAll(
       new Rotate(-20, Rotate.X_AXIS), 
       new Translate(0, 0, -50) 
     ); 

     // Build the Scene Graph 
     Group root = new Group(); 
     root.getChildren().add(camera); 
     root.getChildren().add(box); 

     // Use a SubScene 
     SubScene subScene = new SubScene(
       root, 
       300, 300, 
       true, 
       SceneAntialiasing.BALANCED 
     ); 
     subScene.setFill(Color.ALICEBLUE); 
     subScene.setCamera(camera); 
     Group group = new Group(); 
     group.getChildren().add(subScene); 

     return group; 
    } 

    void update() { 

     if (ph.getSelfIlluminationMap() != null) { 
      ph.setSelfIlluminationMap(null); 
     } else { 
      ph.setSelfIlluminationMap(im); 
     } 

    } 

    @Override 
    public void start(Stage stage) throws Exception { 
     stage.setResizable(false); 
     Scene scene = new Scene(createContent()); 
     stage.setScene(scene); 
     stage.show(); 
     timer.start(); 
    } 

    public static void main(String[] args) { 
     launch(args); 
    } 
} 

但有可能使它淡入和淡出?隨着某種轉變可能?

+0

我有一些想法,但需要對其進行測試...你[編輯]的問題,包括一個完整的例子([MCVE]可以被複制,編譯,並運行),可以作爲一個起點的「眨眼睛」? –

+0

謝謝你的時間!我編輯了帖子。有任何想法嗎?你不必爲任何事情編寫代碼,只是,也許,指向正確的方向。 – tokyo

+0

您是否嘗試使用['Light']的顏色動畫(https://docs.oracle.com/javase/8/javafx/api/javafx/scene/effect/Light.html)? – fabian

回答

2

只是爲了看到效果,我試着動畫specularColor球體的PhongMaterial。從example開始,我遵循顯示here的方法來獲得給定色調的等間距亮度值的顏色查找表。

private final Queue<Color> clut = new LinkedList<>(); 

handle()的執行只是循環遍歷表。

@Override 
public void handle(long now) { 
    redMaterial.setSpecularColor(clut.peek()); 
    clut.add(clut.remove()); 
} 

如果結果是吸引人的,更靈活的方法可以使用的Transition具體子類累積。

private final Animation animation = new Transition() { 

    { 
     setCycleDuration(Duration.millis(1000)); 
     setAutoReverse(true); 
     setCycleCount(INDEFINITE); 
    } 

    @Override 
    protected void interpolate(double d) { 
     redMaterial.setSpecularColor(Color.hsb(LITE.getHue(), 1, d)); 
     redMaterial.setDiffuseColor(Color.hsb(DARK.getHue(), 1, d/2)); 
    } 
}; 

image

import java.util.LinkedList; 
import java.util.Queue; 
import javafx.animation.AnimationTimer; 
import javafx.animation.Animation; 
import javafx.animation.Transition; 
import javafx.application.Application; 
import javafx.geometry.Point3D; 
import javafx.scene.Group; 
import javafx.scene.PerspectiveCamera; 
import javafx.scene.Scene; 
import javafx.scene.input.MouseEvent; 
import javafx.scene.input.ScrollEvent; 
import javafx.scene.paint.Color; 
import javafx.scene.paint.PhongMaterial; 
import javafx.scene.shape.Box; 
import javafx.scene.shape.DrawMode; 
import javafx.scene.shape.Sphere; 
import javafx.scene.transform.Rotate; 
import javafx.scene.transform.Transform; 
import javafx.stage.Stage; 
import javafx.util.Duration; 

/** 
* @see https://stackoverflow.com/a/44447913/230513 
* @see https://stackoverflow.com/a/37755149/230513 
* @see https://stackoverflow.com/a/37743539/230513 
* @see https://stackoverflow.com/a/37370840/230513 
*/ 
public class TriadBox extends Application { 

    private static final double SIZE = 300; 
    private final Content content = Content.create(SIZE); 
    private double mousePosX, mousePosY, mouseOldX, mouseOldY, mouseDeltaX, mouseDeltaY; 

    private static final class Content { 

     private static final double WIDTH = 3; 
     private static final Color LITE = Color.RED; 
     private static final Color DARK = Color.RED.darker().darker(); 
     private final Xform group = new Xform(); 
     private final Group cube = new Group(); 
     private final Group axes = new Group(); 
     private final Box xAxis; 
     private final Box yAxis; 
     private final Box zAxis; 
     private final Box box; 
     private final Sphere sphere; 
     private final PhongMaterial redMaterial = new PhongMaterial(); 
     private final UpdateTimer timer = new UpdateTimer(); 

     private class UpdateTimer extends AnimationTimer { 
      private static final double N = 32d; 
      private final Queue<Color> clut = new LinkedList<>(); 

      public UpdateTimer() { 
       for (int i = 0; i < N; i++) { 
        clut.add(Color.hsb(LITE.getHue(), 1, 1 - (i/N))); 
       } 
       for (int i = 0; i < N; i++) { 
        clut.add(Color.hsb(LITE.getHue(), 1, i/N)); 
       } 
      } 

      @Override 
      public void handle(long now) { 
       redMaterial.setSpecularColor(clut.peek()); 
       clut.add(clut.remove()); 
      } 
     } 

     private final Animation animation = new Transition() { 

      { 
       setCycleDuration(Duration.millis(1000)); 
       setAutoReverse(true); 
       setCycleCount(INDEFINITE); 
      } 

      @Override 
      protected void interpolate(double d) { 
       redMaterial.setSpecularColor(Color.hsb(LITE.getHue(), 1, d)); 
       redMaterial.setDiffuseColor(Color.hsb(DARK.getHue(), 1, d/2)); 
      } 
     }; 

     private static Content create(double size) { 
      Content c = new Content(size); 
      c.cube.getChildren().addAll(c.box, c.sphere); 
      c.axes.getChildren().addAll(c.xAxis, c.yAxis, c.zAxis); 
      c.group.getChildren().addAll(c.cube, c.axes); 
      return c; 
     } 

     private Content(double size) { 
      double edge = 3 * size/4; 
      xAxis = createBox(edge, WIDTH, WIDTH, edge); 
      yAxis = createBox(WIDTH, edge/2, WIDTH, edge); 
      zAxis = createBox(WIDTH, WIDTH, edge/4, edge); 
      box = new Box(edge, edge/2, edge/4); 
      box.setDrawMode(DrawMode.LINE); 
      sphere = new Sphere(8); 
      redMaterial.setDiffuseColor(DARK); 
      redMaterial.setSpecularColor(LITE); 
      sphere.setMaterial(redMaterial); 
      sphere.setTranslateX(edge/2); 
      sphere.setTranslateY(-edge/4); 
      sphere.setTranslateZ(-edge/8); 
     } 

     private Box createBox(double w, double h, double d, double edge) { 
      Box b = new Box(w, h, d); 
      b.setMaterial(new PhongMaterial(Color.AQUA)); 
      b.setTranslateX(-edge/2 + w/2); 
      b.setTranslateY(edge/4 - h/2); 
      b.setTranslateZ(edge/8 - d/2); 
      return b; 
     } 
    } 

    private static class Xform extends Group { 

     private final Point3D px = new Point3D(1.0, 0.0, 0.0); 
     private final Point3D py = new Point3D(0.0, 1.0, 0.0); 
     private Rotate r; 
     private Transform t = new Rotate(); 

     public void rx(double angle) { 
      r = new Rotate(angle, px); 
      this.t = t.createConcatenation(r); 
      this.getTransforms().clear(); 
      this.getTransforms().addAll(t); 
     } 

     public void ry(double angle) { 
      r = new Rotate(angle, py); 
      this.t = t.createConcatenation(r); 
      this.getTransforms().clear(); 
      this.getTransforms().addAll(t); 
     } 

     public void rz(double angle) { 
      r = new Rotate(angle); 
      this.t = t.createConcatenation(r); 
      this.getTransforms().clear(); 
      this.getTransforms().addAll(t); 
     } 
    } 

    @Override 
    public void start(Stage primaryStage) throws Exception { 
     primaryStage.setTitle("JavaFX 3D"); 
     Scene scene = new Scene(content.group, SIZE * 2, SIZE * 2, true); 
     primaryStage.setScene(scene); 
     scene.setFill(Color.BLACK); 
     PerspectiveCamera camera = new PerspectiveCamera(true); 
     camera.setFarClip(SIZE * 6); 
     camera.setTranslateZ(-2 * SIZE); 
     scene.setCamera(camera); 
     scene.setOnMousePressed((MouseEvent e) -> { 
      mousePosX = e.getSceneX(); 
      mousePosY = e.getSceneY(); 
      mouseOldX = e.getSceneX(); 
      mouseOldY = e.getSceneY(); 
     }); 
     scene.setOnMouseDragged((MouseEvent e) -> { 
      mouseOldX = mousePosX; 
      mouseOldY = mousePosY; 
      mousePosX = e.getSceneX(); 
      mousePosY = e.getSceneY(); 
      mouseDeltaX = (mousePosX - mouseOldX); 
      mouseDeltaY = (mousePosY - mouseOldY); 
      if (e.isShiftDown()) { 
       content.group.rz(-mouseDeltaX * 180.0/scene.getWidth()); 
      } else if (e.isPrimaryButtonDown()) { 
       content.group.rx(+mouseDeltaY * 180.0/scene.getHeight()); 
       content.group.ry(-mouseDeltaX * 180.0/scene.getWidth()); 
      } else if (e.isSecondaryButtonDown()) { 
       camera.setTranslateX(camera.getTranslateX() - mouseDeltaX * 0.1); 
       camera.setTranslateY(camera.getTranslateY() - mouseDeltaY * 0.1); 
      } 
     }); 
     scene.setOnScroll((final ScrollEvent e) -> { 
      camera.setTranslateZ(camera.getTranslateZ() + e.getDeltaY()); 
     }); 
     primaryStage.show(); 
     //content.timer.start(); 
     content.animation.play(); 
    } 

    public static void main(String[] args) { 
     launch(args); 
    } 
} 
相關問題