不断检查子弹是否触及节点

zzz*_*zzz 5 java javafx

我有一个非常简单的程序,您可以使用WASDspace进行拍摄。所有的射击和移动动画都有效,但我不确定如何实现一个系统,在该系统中程序不断检查子弹是否接触到一个节点,例如圆圈。

我想我可以用一个ArrayList来存储所有的子弹,然后用一个TimerTask来检查子弹是否接触到一个节点;但我觉得这会减慢程序的速度,而且子弹可能会在等待TimerTask再次出发时穿过他们。

任何建议都会有所帮助。

代码:巴斯德宾

import javafx.application.Application;
import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.layout.Pane;
import javafx.scene.shape.Circle;
import javafx.animation.*;
import javafx.util.Duration;
public class functionalShooter extends Application {
    private String currentDirection = "W";
    public static void main(String[] args){ launch(args);   }
    @Override public void start(Stage stage) throws Exception{
        Pane root = new Pane();
        Scene scene = new Scene(root, 600, 400);
        stage.setScene(scene);
        stage.setResizable(false);
        stage.show();

        Circle player = new Circle(10);
        player.setLayoutX(300);
        player.setLayoutY(200);

        Circle other = new Circle(100, 100, 10);

        root.getChildren().addAll(player, other);

        //key events
        scene.setOnKeyPressed(event -> {
            switch(event.getCode()){
                case A:
                    player.setLayoutX(player.getLayoutX()-10);
                    currentDirection = "A";
                    break;
                case D:
                    player.setLayoutX(player.getLayoutX()+10);
                    currentDirection = "D";
                    break;
                case W:
                    player.setLayoutY(player.getLayoutY()-10);
                    currentDirection = "W";
                    break;
                case S:
                    player.setLayoutY(player.getLayoutY()+10);
                    currentDirection = "S";
                    break;
                case SPACE:
                    if (currentDirection.equals("D")){
                        Circle newCircle = new Circle(player.getLayoutX()+10, player.getLayoutY(), 5);
                        root.getChildren().add(newCircle);
                        shoot(newCircle);
                    }
                    else if (currentDirection.equals("A")){
                        Circle newCircle = new Circle(player.getLayoutX()-10, player.getLayoutY(), 5);
                        root.getChildren().add(newCircle);
                        shoot(newCircle);
                    }
                    else if (currentDirection.equals("S")){
                        Circle newCircle = new Circle(player.getLayoutX(), player.getLayoutY()+10, 5);
                        root.getChildren().add(newCircle);
                        shoot(newCircle);
                    }
                    else {
                        Circle newCircle = new Circle(player.getLayoutX(), player.getLayoutY()-10, 5);
                        root.getChildren().add(newCircle);
                        shoot(newCircle);
                    }
                    break;
            }
        });
    }

    private void shoot(Circle bullet){
        Timeline timeline = new Timeline();
        if (currentDirection.equals("D")){
            KeyValue start = new KeyValue(bullet.translateXProperty(), 0);
            KeyValue end = new KeyValue(bullet.translateXProperty(), 800);
            KeyFrame startF = new KeyFrame(Duration.ZERO, start);
            KeyFrame endF = new KeyFrame(Duration.seconds(10), end);
            timeline.getKeyFrames().addAll(startF, endF);
        }
        else if (currentDirection.equals("A")){
            KeyValue start = new KeyValue(bullet.translateXProperty(), 0);
            KeyValue end = new KeyValue(bullet.translateXProperty(), -800);
            KeyFrame startF = new KeyFrame(Duration.ZERO, start);
            KeyFrame endF = new KeyFrame(Duration.seconds(10), end);
            timeline.getKeyFrames().addAll(startF, endF);
        }
        else if (currentDirection.equals("S")){
            KeyValue start = new KeyValue(bullet.translateYProperty(), 0);
            KeyValue end = new KeyValue(bullet.translateYProperty(), 800);
            KeyFrame startF = new KeyFrame(Duration.ZERO, start);
            KeyFrame endF = new KeyFrame(Duration.seconds(10), end);
            timeline.getKeyFrames().addAll(startF, endF);
        }
        else{
            KeyValue start = new KeyValue(bullet.translateYProperty(), 0);
            KeyValue end = new KeyValue(bullet.translateYProperty(), -800);
            KeyFrame startF = new KeyFrame(Duration.ZERO, start);
            KeyFrame endF = new KeyFrame(Duration.seconds(10), end);
            timeline.getKeyFrames().addAll(startF, endF);
        }
        timeline.setAutoReverse(false);
        timeline.setCycleCount(1);
        timeline.play();
    }
}
Run Code Online (Sandbox Code Playgroud)

tra*_*god 5

您可以使用提供给每个相关的自定义来检查是否bullet相交。下面的片段添加了一个to ,但每个方向都需要一个相同的。该实现是线性的,只是返回不变,但您也可以查看这个抛物线插值器。我还创建了一个类变量,可供. 我毫不犹豫地向空中发射了十几颗子弹。请注意,您不需要值:“将使用播放动画时当前的目标值来合成一个值”。otherShape.intersect()InterpolatorKeyValueInterpolatorshoot()tothershoot()start

\n
private Circle other = new Circle(100, 100, 10);\n\xe2\x80\xa6\nelse {\n    KeyValue end = new KeyValue(bullet.translateYProperty(), -800, new Interpolator() {\n        @Override\n        protected double curve(double t) {\n            if (!Shape.intersect(bullet, other).getBoundsInLocal().isEmpty()) {\n                System.out.println("Intersection");\n            }\n            return t;\n        }\n    });\n    KeyFrame endF = new KeyFrame(Duration.seconds(10), end);\n    timeline.getKeyFrames().addAll(endF);\n}\n
Run Code Online (Sandbox Code Playgroud)\n

更多内容请参见此处此处;经测试:

\n
import javafx.animation.Interpolator;\nimport javafx.animation.KeyFrame;\nimport javafx.animation.KeyValue;\nimport javafx.animation.Timeline;\nimport javafx.application.Application;\nimport javafx.scene.Group;\nimport javafx.stage.Stage;\nimport javafx.scene.Scene;\nimport javafx.scene.shape.Circle;\nimport javafx.scene.shape.Shape;\nimport javafx.util.Duration;\n\n/**\n * @see /sf/answers/2743201191/\n */\npublic class FunctionalShooter extends Application {\n\n    private static final double S = 600;\n    private String currentDirection = "A";\n\n    public static void main(String[] args) {\n        launch(args);\n    }\n\n    @Override\n    public void start(Stage stage) {\n        Group root = new Group();\n        Scene scene = new Scene(root, S, 2 * S / 3);\n        stage.setScene(scene);\n        Circle other = new Circle(S / 3, S / 3, 25);\n        Circle player = new Circle(10);\n        player.setLayoutX(2 * S / 3);\n        player.setLayoutY(S / 3);\n        root.getChildren().addAll(other, player);\n        stage.show();\n\n        //key events\n        scene.setOnKeyPressed(event -> {\n            switch (event.getCode()) {\n                case A -> {\n                    player.setLayoutX(player.getLayoutX() - 10);\n                    currentDirection = "A";\n                }\n                case D -> {\n                    player.setLayoutX(player.getLayoutX() + 10);\n                    currentDirection = "D";\n                }\n                case W -> {\n                    player.setLayoutY(player.getLayoutY() - 10);\n                    currentDirection = "W";\n                }\n                case S -> {\n                    player.setLayoutY(player.getLayoutY() + 10);\n                    currentDirection = "S";\n                }\n                case SPACE -> {\n                    if (currentDirection.equals("D")) {\n                        Circle newCircle = new Circle(player.getLayoutX() + 10, player.getLayoutY(), 5);\n                        root.getChildren().add(newCircle);\n                        shoot(newCircle, other);\n                    } else if (currentDirection.equals("A")) {\n                        Circle newCircle = new Circle(player.getLayoutX() - 10, player.getLayoutY(), 5);\n                        root.getChildren().add(newCircle);\n                        shoot(newCircle, other);\n                    } else if (currentDirection.equals("S")) {\n                        Circle newCircle = new Circle(player.getLayoutX(), player.getLayoutY() + 10, 5);\n                        root.getChildren().add(newCircle);\n                        shoot(newCircle, other);\n                    } else {\n                        Circle newCircle = new Circle(player.getLayoutX(), player.getLayoutY() - 10, 5);\n                        root.getChildren().add(newCircle);\n                        shoot(newCircle, other);\n                    }\n                }\n            }\n        });\n    }\n\n    private static class Intersector extends Interpolator {\n\n        private final Circle bullet;\n        private final Circle other;\n\n        public Intersector(Circle bullet, Circle other) {\n            this.bullet = bullet;\n            this.other = other;\n        }\n\n        @Override\n        protected double curve(double t) {\n            if (!Shape.intersect(bullet, other).getBoundsInLocal().isEmpty()) {\n                System.out.println("Intersect :" + t);\n            }\n            return t;\n        }\n    }\n\n    private void shoot(Circle bullet, Circle other) {\n        Timeline timeline = new Timeline();\n        switch (currentDirection) {\n            case "D" -> {\n                KeyValue end = new KeyValue(bullet.translateXProperty(), S, new Intersector(bullet, other));\n                KeyFrame endF = new KeyFrame(Duration.seconds(10), end);\n                timeline.getKeyFrames().add(endF);\n            }\n            case "A" -> {\n                KeyValue end = new KeyValue(bullet.translateXProperty(), -S, new Intersector(bullet, other));\n                KeyFrame endF = new KeyFrame(Duration.seconds(10), end);\n                timeline.getKeyFrames().add(endF);\n            }\n            case "S" -> {\n                KeyValue end = new KeyValue(bullet.translateYProperty(), S, new Intersector(bullet, other));\n                KeyFrame endF = new KeyFrame(Duration.seconds(10), end);\n                timeline.getKeyFrames().add(endF);\n            }\n            default -> {\n                KeyValue end = new KeyValue(bullet.translateYProperty(), -S, new Intersector(bullet, other));\n                KeyFrame endF = new KeyFrame(Duration.seconds(10), end);\n                timeline.getKeyFrames().add(endF);\n            }\n        }\n        timeline.setAutoReverse(false);\n        timeline.setCycleCount(1);\n        timeline.play();\n    }\n}\n
Run Code Online (Sandbox Code Playgroud)\n