简体   繁体   English

JavaFx:运行时检查PathTransition的当前位置

[英]JavaFx: Check current position of PathTransition while running

I want to get the current position (x,y) of a Circle (javafx.scene.shape.Circle) i am moving via a PathTransition, while the transition is running/happening. 我想获取我正在通过PathTransition移动的圆(javafx.scene.shape.Circle)的当前位置(x,y),而过渡正在运行/正在发生。

So i need some kind of task, that checks the position of the circle every 50 milliseconds (for example). 因此,我需要执行某种任务,例如每50毫秒检查一次圆的位置。

I also tried this solution Current circle position of javafx transition which was suggested on Stack Overflow, but i didn't seem to work for me. 我也尝试过此解决方案该问题在堆栈溢出中建议了javafx过渡的当前圆位置 ,但我似乎没有用。

Circle projectile = new Circle(Playground.PROJECTILE_SIZE, Playground.PROJECTILE_COLOR);

root.getChildren().add(projectile);

double duration = distance / Playground.PROJECTILE_SPEED;

double xOff = (0.5-Math.random())*Playground.WEAPON_OFFSET;
double yOff = (0.5-Math.random())*Playground.WEAPON_OFFSET;

Line shotLine = new Line(player.getCurrentX(), player.getCurrentY(), aimLine.getEndX() + xOff, aimLine.getEndY() + yOff);

shotLine.setEndX(shotLine.getEndX() + (Math.random()*Playground.WEAPON_OFFSET));

PathTransition pt = new PathTransition(Duration.seconds(duration), shotLine, projectile);

// Linear movement for linear speed
pt.setInterpolator(Interpolator.LINEAR);

pt.setOnFinished(new EventHandler<ActionEvent>() {
    public void handle(ActionEvent event) {
    // Remove bullet after hit/expiration
    projectile.setVisible(false);
    root.getChildren().remove(projectile);
    }
});

projectile.translateXProperty().addListener(new ChangeListener<Number>() {

    @Override
    public void changed(ObservableValue<? extends Number> observable, Number oldValue, Number newValue) {
    double x = collider.getTranslateX() - projectile.getTranslateX();
    double y = collider.getTranslateY() - projectile.getTranslateY();

    double distance = Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2));

    System.out.println("Distance: "+ distance);

    if (distance < 50) {
        System.out.println("hit");
    }
    }
});

pt.play();

A PathTransition will move a node by manipulating its translateX and translateY properties. PathTransition将通过操纵其translateXtranslateY属性来移动节点。 (A TranslateTransition works the same way.) TranslateTransition工作方式相同。)

It's hard to answer your question definitively as your code is so incomplete, but if the projectile and collider have the same parent in the scene graph, converting the initial coordinates of the projectile and collider by calling localToParent will give the coordinates in the parent, including the translation. 由于代码如此不完整,很难完全回答您的问题,但是如果projectilecollider在场景图中具有相同的父代,则通过调用localToParent转换projectilecollider的初始坐标将给出父代中的坐标,包括译文。 So you can observe the translateX and translateY properties and use that conversion to check for a collision. 因此,您可以观察translateXtranslateY属性,并使用该转换来检查冲突。 If they have different parents, you can do the same with localToScene instead and just convert both to coordinates relative to the scene. 如果他们有不同的父级,则可以使用localToScene代替,将它们都转换为相对于场景的坐标。

Here's a quick SSCCE. 这是一个快速的SSCCE。 Use the left and right arrows to aim, space to shoot: 使用向左和向右箭头瞄准,射击的空间:

import javafx.animation.Animation;
import javafx.animation.TranslateTransition;
import javafx.application.Application;
import javafx.beans.binding.Bindings;
import javafx.beans.binding.BooleanBinding;
import javafx.geometry.Point2D;
import javafx.scene.Scene;
import javafx.scene.input.KeyCode;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.scene.shape.Line;
import javafx.scene.transform.Rotate;
import javafx.stage.Stage;
import javafx.util.Duration;

public class ShootingGame extends Application {

    @Override
    public void start(Stage primaryStage) {
        final double width = 400 ;
        final double height = 400 ;

        final double targetRadius = 25 ;
        final double projectileRadius = 5 ;

        final double weaponLength = 25 ;

        final double weaponX = width / 2 ;
        final double weaponStartY = height ;
        final double weaponEndY = height - weaponLength ;

        final double targetStartX = targetRadius ;
        final double targetY = targetRadius * 2 ;;

        Pane root = new Pane();
        Circle target = new Circle(targetStartX, targetY, targetRadius, Color.BLUE);
        TranslateTransition targetMotion = new TranslateTransition(Duration.seconds(2), target);
        targetMotion.setByX(350);
        targetMotion.setAutoReverse(true);
        targetMotion.setCycleCount(Animation.INDEFINITE);
        targetMotion.play();

        Line weapon = new Line(weaponX, weaponStartY, weaponX, weaponEndY);
        weapon.setStrokeWidth(5);
        Rotate weaponRotation = new Rotate(0, weaponX, weaponStartY);
        weapon.getTransforms().add(weaponRotation);

        Scene scene = new Scene(root, width, height);
        scene.setOnKeyPressed(e -> {
            if (e.getCode() == KeyCode.LEFT) {
                weaponRotation.setAngle(Math.max(-45, weaponRotation.getAngle() - 2));
            }
            if (e.getCode() == KeyCode.RIGHT) {
                weaponRotation.setAngle(Math.min(45, weaponRotation.getAngle() + 2));
            }
            if (e.getCode() == KeyCode.SPACE) {

                Point2D weaponEnd = weapon.localToParent(weaponX, weaponEndY);

                Circle projectile = new Circle(weaponEnd.getX(), weaponEnd.getY(), projectileRadius);

                TranslateTransition shot = new TranslateTransition(Duration.seconds(1), projectile);
                shot.setByX(Math.tan(Math.toRadians(weaponRotation.getAngle())) * height);
                shot.setByY(-height);
                shot.setOnFinished(event -> root.getChildren().remove(projectile));

                BooleanBinding hit = Bindings.createBooleanBinding(() -> {
                    Point2D targetLocation = target.localToParent(targetStartX, targetY);
                    Point2D projectileLocation = projectile.localToParent(weaponEnd);
                    return (targetLocation.distance(projectileLocation) < targetRadius + projectileRadius) ;
                }, projectile.translateXProperty(), projectile.translateYProperty());

                hit.addListener((obs, wasHit, isNowHit) -> {
                    if (isNowHit) {
                        System.out.println("Hit");
                        root.getChildren().remove(projectile);
                        root.getChildren().remove(target);
                        targetMotion.stop();
                        shot.stop();
                    }
                });

                root.getChildren().add(projectile);
                shot.play();
            }
        });

        root.getChildren().addAll(target, weapon);

        primaryStage.setScene(scene);
        primaryStage.show();
    }

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM