アニメーション
これを行うことができますが、考慮遷移にフリスビーの概念を取ることはうまくいくだろういくつかの方法があります。ここに公式のチュートリアルがあります:使用可能なものの中から
は、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
(ドラッグアンドドロップ実装でカーソル変化注)

