Here is a code with "teleportation" problem.
Start code:
....
....
public class JavaFXApplication1 extends Application {
.....
.....
@Override
public void start(Stage primaryStage) {
//test(primaryStage);
final Human human=new Human();
final Human human2=new Human();
final Group root = new Group(human,human2);
Scene scene = new Scene(root, 300, 300);
scene.setOnMousePressed(new EventHandler<MouseEvent>() {
@Override
public void handle(MouseEvent t) {
human.runTo(t.getX(), t.getY());
human2.runTo(t.getX()-70, t.getY());
//System.out.println("KK");
}
});
scene.setOnScroll(new EventHandler<ScrollEvent>() {
@Override
public void handle(ScrollEvent t) {
System.out.println("Scrolling! "+t.getDeltaY());
}
});
Rectangle2D primaryScreenBounds = Screen.getPrimary().getVisualBounds();
//set Stage boundaries to visible bounds of the main screen
// primaryStage.setX(primaryScreenBounds.getMinX());
// primaryStage.setY(primaryScreenBounds.getMinY());
// primaryStage.setWidth(primaryScreenBounds.getWidth());
// primaryStage.setHeight(primaryScreenBounds.getHeight());
//primaryStage.setFullScreen(true);
//primaryStage.setIconified(false);
//primaryStage.setOpacity(0.1);
primaryStage.initStyle(StageStyle.TRANSPARENT);
//primaryStage.getOwner().setOpacity(0.2);
primaryStage.setScene(scene);
primaryStage.show();
}
....
....
....
}
Class with "teleportations":
package game.human;
import javafx.animation.*;
import javafx.event.ActionEvent;
import javafx.event.Event;
import javafx.event.EventHandler;
import javafx.scene.Group;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.transform.Rotate;
import javafx.scene.transform.Scale;
import javafx.util.Duration;
/**
*
* @author Me
*/
public class Human extends Group{
private Image imghuman = new Image(Human.class.getResource("images/human.png").toString());
private Image imghumanR = new Image(Human.class.getResource("images/human_r.png").toString());
private Image imghumanR2 = new Image(Human.class.getResource("images/human_r2.png").toString());
private Image imghumanL = new Image(Human.class.getResource("images/human_l.png").toString());
private Image imghumanL2 = new Image(Human.class.getResource("images/human_l2.png").toString());
private ImageView human = new ImageView(imghuman);
private ImageView humanR = new ImageView(imghumanR);
private ImageView humanR2 = new ImageView(imghumanR2);
private ImageView humanL = new ImageView(imghumanL);
private ImageView humanL2 = new ImageView(imghumanL2);
//private Group HUMAN;
private TranslateTransition current;
private Timeline LEFT_MOVEMENT;
private Timeline RIGHT_MOVEMENT;
private static final double SPEED=50;
final Human SELF;
public Human() {
super(new ImageView(new Image(Human.class.getResource("images/human.png").toString())));
SELF=this;
init(this);
//this.getTransforms().add(new Scale(0.1,0.1));
}
private void init(final Human me){
LEFT_MOVEMENT = TimelineBuilder.create().cycleCount(Animation.INDEFINITE).keyFrames(
new KeyFrame(new Duration(250), new EventHandler() {
@Override
public void handle(Event t) {
me.getChildren().setAll(humanL);
}
}),
new KeyFrame(new Duration(500), new EventHandler() {
@Override
public void handle(Event t) {
me.getChildren().setAll(humanL2);
}
})).build();
RIGHT_MOVEMENT = TimelineBuilder.create().cycleCount(Animation.INDEFINITE).keyFrames(
new KeyFrame(new Duration(250), new EventHandler() {
@Override
public void handle(Event t) {
me.getChildren().setAll(humanR);
}
}),
new KeyFrame(new Duration(500), new EventHandler() {
@Override
public void handle(Event t) {
me.getChildren().setAll(humanR2);
}
})).build();
current = TranslateTransitionBuilder.create().fromX(0).toX(10).fromY(0).toY(10).node(me).duration(Duration.millis(4000)).onFinished(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent t) {
//startAnimation();
if (RIGHT_MOVEMENT.statusProperty().get().compareTo(Animation.Status.RUNNING) == 0) {
RIGHT_MOVEMENT.stop();
me.getChildren().setAll(human);
}
if (LEFT_MOVEMENT.statusProperty().get().compareTo(Animation.Status.RUNNING) == 0) {
LEFT_MOVEMENT.stop();
me.getChildren().setAll(human);
}
}
}).interpolator(Interpolator.LINEAR).build();
}
public void runTo(double toX, double toY) {
if (current != null) {
if (!current.statusProperty().get().toString().equals(Animation.Status.STOPPED.toString())) {
if (RIGHT_MOVEMENT.statusProperty().get().compareTo(Animation.Status.RUNNING) == 0) {
RIGHT_MOVEMENT.stop();
this.getChildren().setAll(human);
}
if (LEFT_MOVEMENT.statusProperty().get().compareTo(Animation.Status.RUNNING) == 0) {
LEFT_MOVEMENT.stop();
this.getChildren().setAll(human);
}
current.stop();
}
double fromX=current.getNode().getTranslateX();
double fromY=current.getNode().getTranslateY();
double distance=Math.ceil(Math.sqrt(Math.pow(fromX-toX,2)+Math.pow(fromY-toY, 2))*1000)/1000; // Теорема Пифагора!!!
//System.out.println(distance);
if (current.getNode().getTranslateX() <= toX) {
RIGHT_MOVEMENT.play();
} else {
LEFT_MOVEMENT.play();
}
Double time=Double.valueOf(Math.ceil(distance/SPEED*100)/100);
Duration d=Duration.millis(time*1000);
If I shall uncomment this code and Duration d is not constant (it is some variable) teleportation of "human" will sometimes occurs. I have no found dependence between new coordinates toX and toY, duration (it was not zero) and teleportation effect. If Duration d is constant teleportation never occurs:
// current.setFromX(fromX);
// current.setFromY(fromY);
// current.setToX(toX);
// current.setToY(toY);
// current.setDuration(d);
If I am creating every time a new TranslateTransition object there is no any teleportation.
current = TranslateTransitionBuilder.create().fromX(fromX).toX(toX).fromY(fromY).toY(toY).node(SELF).duration(d).onFinished(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent t) {
//startAnimation();
if (RIGHT_MOVEMENT.statusProperty().get().compareTo(Animation.Status.RUNNING) == 0) {
RIGHT_MOVEMENT.stop();
SELF.getChildren().setAll(human);
}
if (LEFT_MOVEMENT.statusProperty().get().compareTo(Animation.Status.RUNNING) == 0) {
LEFT_MOVEMENT.stop();
SELF.getChildren().setAll(human);
}
}
}).interpolator(Interpolator.LINEAR).build();
//System.out.println("fromX "+fromX+" fromY "+fromY+" toX "+toX+" toY "+toY+" time "+time+" distance "+distance+" duration "+d.toString());
//System.out.println("fromX "+current.getFromX()+" fromY "+current.getFromY()+" toX "+current.getToX()+" toY "+current.getToY()+" time "+time+" distance "+distance+" duration "+current.getTotalDuration().toString());
current.play();
}
}
}
This is a simple class. When user makes some mouse click on scene then calls:
scene.setOnMousePressed(new EventHandler<MouseEvent>() {
@Override
public void handle(MouseEvent t) {
human.runTo(t.getX(), t.getY());
human2.runTo(t.getX()-70, t.getY());
//System.out.println("KK");
}
});
Sometimes, when code is and duration is some variable but not a constant:
current.setFromX(fromX);
current.setFromY(fromY);
current.setToX(toX);
current.setToY(toY);
current.setDuration(d);
human teleports into toX toY coordinates without any animation.
I think that this is a bug.
Start code:
....
....
public class JavaFXApplication1 extends Application {
.....
.....
@Override
public void start(Stage primaryStage) {
//test(primaryStage);
final Human human=new Human();
final Human human2=new Human();
final Group root = new Group(human,human2);
Scene scene = new Scene(root, 300, 300);
scene.setOnMousePressed(new EventHandler<MouseEvent>() {
@Override
public void handle(MouseEvent t) {
human.runTo(t.getX(), t.getY());
human2.runTo(t.getX()-70, t.getY());
//System.out.println("KK");
}
});
scene.setOnScroll(new EventHandler<ScrollEvent>() {
@Override
public void handle(ScrollEvent t) {
System.out.println("Scrolling! "+t.getDeltaY());
}
});
Rectangle2D primaryScreenBounds = Screen.getPrimary().getVisualBounds();
//set Stage boundaries to visible bounds of the main screen
// primaryStage.setX(primaryScreenBounds.getMinX());
// primaryStage.setY(primaryScreenBounds.getMinY());
// primaryStage.setWidth(primaryScreenBounds.getWidth());
// primaryStage.setHeight(primaryScreenBounds.getHeight());
//primaryStage.setFullScreen(true);
//primaryStage.setIconified(false);
//primaryStage.setOpacity(0.1);
primaryStage.initStyle(StageStyle.TRANSPARENT);
//primaryStage.getOwner().setOpacity(0.2);
primaryStage.setScene(scene);
primaryStage.show();
}
....
....
....
}
Class with "teleportations":
package game.human;
import javafx.animation.*;
import javafx.event.ActionEvent;
import javafx.event.Event;
import javafx.event.EventHandler;
import javafx.scene.Group;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.transform.Rotate;
import javafx.scene.transform.Scale;
import javafx.util.Duration;
/**
*
* @author Me
*/
public class Human extends Group{
private Image imghuman = new Image(Human.class.getResource("images/human.png").toString());
private Image imghumanR = new Image(Human.class.getResource("images/human_r.png").toString());
private Image imghumanR2 = new Image(Human.class.getResource("images/human_r2.png").toString());
private Image imghumanL = new Image(Human.class.getResource("images/human_l.png").toString());
private Image imghumanL2 = new Image(Human.class.getResource("images/human_l2.png").toString());
private ImageView human = new ImageView(imghuman);
private ImageView humanR = new ImageView(imghumanR);
private ImageView humanR2 = new ImageView(imghumanR2);
private ImageView humanL = new ImageView(imghumanL);
private ImageView humanL2 = new ImageView(imghumanL2);
//private Group HUMAN;
private TranslateTransition current;
private Timeline LEFT_MOVEMENT;
private Timeline RIGHT_MOVEMENT;
private static final double SPEED=50;
final Human SELF;
public Human() {
super(new ImageView(new Image(Human.class.getResource("images/human.png").toString())));
SELF=this;
init(this);
//this.getTransforms().add(new Scale(0.1,0.1));
}
private void init(final Human me){
LEFT_MOVEMENT = TimelineBuilder.create().cycleCount(Animation.INDEFINITE).keyFrames(
new KeyFrame(new Duration(250), new EventHandler() {
@Override
public void handle(Event t) {
me.getChildren().setAll(humanL);
}
}),
new KeyFrame(new Duration(500), new EventHandler() {
@Override
public void handle(Event t) {
me.getChildren().setAll(humanL2);
}
})).build();
RIGHT_MOVEMENT = TimelineBuilder.create().cycleCount(Animation.INDEFINITE).keyFrames(
new KeyFrame(new Duration(250), new EventHandler() {
@Override
public void handle(Event t) {
me.getChildren().setAll(humanR);
}
}),
new KeyFrame(new Duration(500), new EventHandler() {
@Override
public void handle(Event t) {
me.getChildren().setAll(humanR2);
}
})).build();
current = TranslateTransitionBuilder.create().fromX(0).toX(10).fromY(0).toY(10).node(me).duration(Duration.millis(4000)).onFinished(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent t) {
//startAnimation();
if (RIGHT_MOVEMENT.statusProperty().get().compareTo(Animation.Status.RUNNING) == 0) {
RIGHT_MOVEMENT.stop();
me.getChildren().setAll(human);
}
if (LEFT_MOVEMENT.statusProperty().get().compareTo(Animation.Status.RUNNING) == 0) {
LEFT_MOVEMENT.stop();
me.getChildren().setAll(human);
}
}
}).interpolator(Interpolator.LINEAR).build();
}
public void runTo(double toX, double toY) {
if (current != null) {
if (!current.statusProperty().get().toString().equals(Animation.Status.STOPPED.toString())) {
if (RIGHT_MOVEMENT.statusProperty().get().compareTo(Animation.Status.RUNNING) == 0) {
RIGHT_MOVEMENT.stop();
this.getChildren().setAll(human);
}
if (LEFT_MOVEMENT.statusProperty().get().compareTo(Animation.Status.RUNNING) == 0) {
LEFT_MOVEMENT.stop();
this.getChildren().setAll(human);
}
current.stop();
}
double fromX=current.getNode().getTranslateX();
double fromY=current.getNode().getTranslateY();
double distance=Math.ceil(Math.sqrt(Math.pow(fromX-toX,2)+Math.pow(fromY-toY, 2))*1000)/1000; // Теорема Пифагора!!!
//System.out.println(distance);
if (current.getNode().getTranslateX() <= toX) {
RIGHT_MOVEMENT.play();
} else {
LEFT_MOVEMENT.play();
}
Double time=Double.valueOf(Math.ceil(distance/SPEED*100)/100);
Duration d=Duration.millis(time*1000);
If I shall uncomment this code and Duration d is not constant (it is some variable) teleportation of "human" will sometimes occurs. I have no found dependence between new coordinates toX and toY, duration (it was not zero) and teleportation effect. If Duration d is constant teleportation never occurs:
// current.setFromX(fromX);
// current.setFromY(fromY);
// current.setToX(toX);
// current.setToY(toY);
// current.setDuration(d);
If I am creating every time a new TranslateTransition object there is no any teleportation.
current = TranslateTransitionBuilder.create().fromX(fromX).toX(toX).fromY(fromY).toY(toY).node(SELF).duration(d).onFinished(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent t) {
//startAnimation();
if (RIGHT_MOVEMENT.statusProperty().get().compareTo(Animation.Status.RUNNING) == 0) {
RIGHT_MOVEMENT.stop();
SELF.getChildren().setAll(human);
}
if (LEFT_MOVEMENT.statusProperty().get().compareTo(Animation.Status.RUNNING) == 0) {
LEFT_MOVEMENT.stop();
SELF.getChildren().setAll(human);
}
}
}).interpolator(Interpolator.LINEAR).build();
//System.out.println("fromX "+fromX+" fromY "+fromY+" toX "+toX+" toY "+toY+" time "+time+" distance "+distance+" duration "+d.toString());
//System.out.println("fromX "+current.getFromX()+" fromY "+current.getFromY()+" toX "+current.getToX()+" toY "+current.getToY()+" time "+time+" distance "+distance+" duration "+current.getTotalDuration().toString());
current.play();
}
}
}
This is a simple class. When user makes some mouse click on scene then calls:
scene.setOnMousePressed(new EventHandler<MouseEvent>() {
@Override
public void handle(MouseEvent t) {
human.runTo(t.getX(), t.getY());
human2.runTo(t.getX()-70, t.getY());
//System.out.println("KK");
}
});
Sometimes, when code is and duration is some variable but not a constant:
current.setFromX(fromX);
current.setFromY(fromY);
current.setToX(toX);
current.setToY(toY);
current.setDuration(d);
human teleports into toX toY coordinates without any animation.
I think that this is a bug.