2016-04-23 18 views
1

JavaFXでマウスドラッグイベントを実装する正しい方法に関する質問があります。マウス/ドラッグイベントでのJavaFXフリスビーの移動

マイplayGame()方法は、現在onMouseClickedを利用している、しかし、これは理想的には、今

のためだけのプレースホルダーですが、私は「フリスビー」はマウスドラッグの方向に「翻弄」されるようにしたいと思います。

これを行うにはどうすればよいでしょうか?

package FrisbeeToss; 

import javafx.application.Application; 
import javafx.scene.Parent; 
import javafx.scene.Scene; 
import javafx.scene.layout.Pane; 
import javafx.scene.paint.Color; 
import javafx.scene.shape.Circle; 
import javafx.scene.text.Text; 
import javafx.stage.Stage; 

public class FrisbeeTossMain extends Application { 

private Text info = new Text(); 
private Entity frisbee, target; 

private static final int APP_W = 800; 
private static final int APP_H = 600; 

private static class Entity extends Parent { 
    public Entity(double x, double y, double r, Color c) { 
     setTranslateX(x); 
     setTranslateY(y); 
     Circle circ = new Circle(r, c); 
     getChildren().add(circ); 
    } 
} 

private Parent createContent() { 
    Pane root = new Pane(); 
    root.setPrefSize(APP_W, APP_H); 

    info.setTranslateX(50); 
    info.setTranslateY(50); 

    target = new Entity(APP_W /2, APP_H /2, 75, Color.RED); 
    frisbee = new Entity(APP_W -20, APP_H -20, 60, Color.GREEN); 

    root.getChildren().addAll(info, target, frisbee); 

    return root; 
} 

private void checkCollision(Entity a, Entity b){ 
    if (a.getBoundsInParent().intersects(b.getBoundsInParent())) { 
     info.setText("Target caught frisbee!"); 
    } 
    else { 
     info.setText(""); 
    } 
} 

private void playGame() { 
    frisbee.setOnMouseClicked(event -> { 
     System.out.println("Frisbee clicked"); 

     checkCollision(frisbee, target); 
    }); 
} 

@Override 
public void start(Stage primaryStage) throws Exception { 
    Scene scene = new Scene(createContent()); 

    primaryStage.setTitle("Frisbee Toss"); 
    primaryStage.setScene(scene); 
    primaryStage.show(); 

    playGame(); 

    } 
} 

答えて

1

アニメーション

これを行うことができますが、考慮遷移にフリスビーの概念を取ることはうまくいくだろういくつかの方法があります。ここに公式のチュートリアルがあります:使用可能なものの中から

は、PathTransitionはうまく動作します。ユーザーがフリスビーを「投げる」方向を変換することで、フリスビーNodeが従うPathを生成することができます。適用


をあなたもフリスビーフリスビーのスピンのようブーメラン

のように動作させることができサイクルを変更し、反転を適用することで、あなたもRotationTransitionの利点を取ることができるし、パスに沿った動きと一緒にそれを適用しますアニメーション

フリスビーにはmouseReleasedイベントだけで上記のトランジションを適用することができますが、具体的に言及したように、以下のコードを変更して両方のアプローチを示しています。リリースイベントの一つの、あなたはドラッグアンドドロップ機能の詳細を読みたい場合は、ドラッグ・アンド・ドロップ

を使用して、他の、それはここではカバーされています:

以下の実装では、オリジナルのソース

に行われた


マイナー変更は、私はあなたのを削除しましたEntityは目的がちょうど私がstatic宣言をも削除したCircle

を作成するように見せかけて、何も添加しなかったとしてクラスはCircleに置き換えます。この特定の例では、それらを持つことや削除することに何のメリットもありませんが、staticキーワードは、必要な場所でのみ使用するようにしてください。


実装:うまくいけば、この人気の記事は、より良い理由を説明することができ

私はいくつかのステップを明確にするために、コメントを追加しましたが、何かが明確でない場合、またはいくつかの改善点があります。コメントを追加してください。

mouseReleased approac H:

public class FrisbeeTossMain extends Application { 
    private Pane root; 
    private Text info = new Text(); 
    private Circle frisbee, target; 
    private PathTransition transition; 

    private final int APP_W = 800; 
    private final int APP_H = 600; 
    private final double frisbeeX = APP_W -20; 
    private final double frisbeeY = APP_H -20; 

    private Parent createContent() { 
     root = new Pane(); 
     root.setPrefSize(APP_W, APP_H); 

     info.setTranslateX(50); 
     info.setTranslateY(50); 

     target = new Circle(75, Color.RED); 
     target.setLayoutX(APP_W /2); 
     target.setLayoutY(APP_H /2); 

     frisbee = new Circle(60, Color.GREEN); 
     frisbee.setLayoutX(frisbeeX); 
     frisbee.setLayoutY(frisbeeY); 
     frisbee.setFill(new LinearGradient(0, 0, 1, 0, true, CycleMethod.NO_CYCLE, 
       new Stop[] { new Stop(0, Color.BLACK), new Stop(1, Color.GREEN)})); 

     SimpleBooleanProperty isFrisbeeVisuallyCollidingWithTarget = new SimpleBooleanProperty(false); 
     frisbee.boundsInParentProperty().addListener((observable, oldValue, newValue) -> { 
      isFrisbeeVisuallyCollidingWithTarget.set(
        Shape.intersect(frisbee, target).getBoundsInParent().getWidth() >= 0 ? true : false); 
     }); 

     isFrisbeeVisuallyCollidingWithTarget.addListener((observable, oldValue, newValue) -> { 
      if(newValue && transition != null){ 
       //Stop the animation making it appear as though the frisbee was caught 
       transition.stop(); 
      } 
     }); 

     info.textProperty().bind(Bindings.when(isFrisbeeVisuallyCollidingWithTarget) 
       .then("Target caught frisbee!").otherwise("")); 
     root.getChildren().addAll(info, target, frisbee); 

     return root; 
    } 

    private void playGame() { 
     frisbee.setOnMouseReleased(event -> { 
      //Starting point for the line 
      double fromX = frisbeeX - frisbee.getRadius(); 
      double fromY = frisbeeY - frisbee.getRadius(); 

      //Only "throw" the frisbee if the user has released outside of the frisbee itself 
      if(frisbee.getBoundsInParent().contains(event.getSceneX(), event.getSceneY())){ 
       return; 
      } 

      //Create a path between the frisbee and released location 
      Line line = new Line(fromX, fromY, event.getSceneX(), event.getSceneY()); 
      transition = new PathTransition(Duration.seconds(1), line, frisbee); 
      transition.setAutoReverse(true); //Set the node to reverse along the path 
      transition.setCycleCount(2); //2 cycles, first to navigate the path, second to return 
      frisbee.relocate(0, 0); //Allow the path to control the location of the frisbee 

      RotateTransition rotateTransition = 
        new RotateTransition(Duration.seconds(1), frisbee); 
      rotateTransition.setByAngle(360f); 
      rotateTransition.setCycleCount(2); 
      rotateTransition.setAutoReverse(true); 

      rotateTransition.play(); 
      transition.play(); 
     }); 
    } 

    @Override 
    public void start(Stage primaryStage) throws Exception { 
     Scene scene = new Scene(createContent()); 

     primaryStage.setTitle("Frisbee Toss"); 
     primaryStage.setScene(scene); 
     primaryStage.show(); 

     playGame(); 
    } 
} 

ドラッグアンドドロップの実装:追加

private void playGame() { 
    frisbee.setId("frisbee"); 

    frisbee.setOnDragDetected(event -> { 
     Dragboard db = frisbee.startDragAndDrop(TransferMode.ANY); 
     ClipboardContent content = new ClipboardContent(); 
     // Store node ID in order to know what is dragged. 
     content.putString(frisbee.getId()); 
     db.setContent(content); 
     event.consume(); 
    }); 

    root.setOnDragOver(event -> { 
     event.acceptTransferModes(TransferMode.COPY_OR_MOVE); 
     event.consume(); 
    }); 

    root.setOnDragDropped(event -> { 
     //Starting point for the line 
     double fromX = frisbeeX - frisbee.getRadius(); 
     double fromY = frisbeeY - frisbee.getRadius(); 

     //Only "throw" the frisbee if the user has released outside of the frisbee itself 
     if(frisbee.getBoundsInParent().contains(event.getSceneX(), event.getSceneY())){ 
      return; 
     } 

     //Create a path between the frisbee and released location 
     Line line = new Line(fromX, fromY, event.getSceneX(), event.getSceneY()); 
     transition = new PathTransition(Duration.seconds(1), line, frisbee); 
     transition.setAutoReverse(true); //Set the node to reverse along the path 
     transition.setCycleCount(2); //2 cycles, first to navigate the path, second to return 
     frisbee.relocate(0, 0); //Allow the path to control the location of the frisbee 

     transition.setOnFinished(finishedEvent -> { 
      event.setDropCompleted(true); 
      event.consume(); 
     }); 
     transition.play(); 
    }); 
} 


唯一の違いは、上からであるplayGame方法の範囲内でありますローテーション:

回転が再生する前に、事前に保留以下のスニペットによって適用することができますPathTransition:あなたが作ることができる

RotateTransition rotateTransition = new RotateTransition(Duration.seconds(1), frisbee); 
rotateTransition.setByAngle(360f); 
rotateTransition.setCycleCount(2); 
rotateTransition.setAutoReverse(true); 
rotateTransition.play(); 

予告可能なブロックとは反対に、フリスビーにGradientFillを適用することにより、回転以上色

例:

frisbee.setFill(new LinearGradient(0, 0, 1, 0, true, CycleMethod.NO_CYCLE, 
    new Stop[] { new Stop(0, Color.BLACK), new Stop(1, Color.GREEN)})); 


ビジュアル出力

順序:mouseReleased | drag-and-drop | mouseReleased with rotation

(ドラッグアンドドロップ実装でカーソル変化注)

Frisbee Released Frisbee DragFrisbee Released with rotation