動畫
有幾種方法可以這樣做,而是採取了飛盤的概念,考慮到過渡將工作做好。這裏有一個官方教程:
從這些可用,PathTransition
將工作做好。通過轉換用戶「扔」飛盤的方向,您可以生成飛盤Node
可以遵循的Path
。通過修改週期和運用逆轉,你也可以讓飛盤像一個迴旋鏢
由於飛盤的旋轉,你也可以採取RotationTransition
的優勢,並把它旁邊的移動路徑上
應用動畫
你可以在飛盤上應用上面的跳轉事件,只是一個mouseReleased
事件,但正如你特別提到的拖動,我修改了下面的代碼來顯示兩種方法。一個與釋放的事件,並使用拖放和拖放
如果您想了解更多關於拖動和拖放功能,另外,都能在這裏找到:
原始源
做在下面的實現中的微小變化,我已經刪除您Entity
類與Circle
爲Entity
沒有添加任何,目的似乎取代它只是創造一個Circle
我也去掉了static
聲明。在這個特定的例子中,沒有任何好處,但只有在需要的地方使用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();
}
}
拖動和放下實現:
唯一的區別是從上面是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();
});
}
添加輪換:
旋轉可以通過預先掛起以下片段在播放前應用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
(請注意,在拖動和拖放實現光標變化)