对角线和矩形之间的冲突检测不正确

gstyhher  于 2021-07-06  发布在  Java
关注(0)|答案(0)|浏览(213)

我正在开发一个程序,其中“子弹线”被用作敌方ai探测玩家所在位置(并相应地向玩家射击)的一种方式。在我下面的最小可复制的例子中,玩家是蓝方,有一堆线从敌人(红方)的位置射出。当线的边界与玩家的边界相交时,线应该变成红色,但事实并非如此。即使玩家没有碰到线,线也会变成红色。
请看这段视频以更好地了解我的问题:https://youtu.be/7jpv-lynyyu
下面是我的代码(minimalexample.java):

package main;

import javafx.animation.AnimationTimer;
import javafx.application.Application;
import static javafx.application.Application.launch;
import javafx.scene.Scene;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Line;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;

/**
 *
 * @author Preston Tang
 */
public class MinimalExample extends Application {

    private Pane graphics;

    //Keyboard Controls
    private boolean w, a, s, d;

    private Rectangle player, enemy;

    private final double GRIDCELLWIDTH = 25;
    private final double WIDTH = 800;
    private final double HEIGHT = 550;
    private final double TANKWIDTH = 20;

    private final int NUMBEROFBULLETLINES = 128;

    private Line[] bulletLines;

    @Override
    public void start(Stage stage) {
        graphics = new Pane();

        //Creating the grid
        for (int r = 0; r < WIDTH / GRIDCELLWIDTH; r++) {
            for (int c = 0; c < HEIGHT / GRIDCELLWIDTH; c++) {
                Rectangle gridCell = new Rectangle();
                gridCell.setX(GRIDCELLWIDTH * r);
                gridCell.setY(GRIDCELLWIDTH * c);
                gridCell.setWidth(GRIDCELLWIDTH);
                gridCell.setHeight(GRIDCELLWIDTH);

                if (r == 0 || c == 0
                        || r == WIDTH / GRIDCELLWIDTH - 1
                        || c == HEIGHT / GRIDCELLWIDTH - 1) {
                    gridCell.setFill(Color.rgb(75, 75, 75));
                } else {
                    gridCell.setFill(Color.WHITE);
                }
                gridCell.setStroke(Color.BLACK);
                gridCell.setStrokeWidth(0.1);

                graphics.getChildren().add(gridCell);
            }
        }

        //Initializing the player and the enemy
        player = new Rectangle();
        player.setX(WIDTH / 4D);
        player.setY(HEIGHT / 2D);
        player.setWidth(TANKWIDTH);
        player.setHeight(TANKWIDTH);
        player.setFill(Color.BLUE);
        player.setStroke(Color.BLACK);

        enemy = new Rectangle();
        enemy.setX(WIDTH / 1.5D);
        enemy.setY(HEIGHT / 2D);
        enemy.setWidth(TANKWIDTH);
        enemy.setHeight(TANKWIDTH);
        enemy.setFill(Color.RED);
        enemy.setStroke(Color.BLACK);

        graphics.getChildren().add(player);
        graphics.getChildren().add(enemy);

        //Creating the lines
        bulletLines = new Line[NUMBEROFBULLETLINES];
        double angle = -Math.PI;

        for (int i = 0; i < bulletLines.length; i++) {
            Line line = new Line();
            double startingX = enemy.getX() + enemy.getWidth() / 2;
            double startingY = enemy.getY() + enemy.getHeight() / 2;

            line.setStartX(startingX);
            line.setStartY(startingY);
            line.setEndX(startingX + Math.cos(angle) * 200);
            line.setEndY(startingY + Math.sin(angle) * 200);

            angle += Math.PI / (NUMBEROFBULLETLINES / 2);

            bulletLines[i] = line;
            graphics.getChildren().add(line);
        }

        stage.setTitle("Minimal Reproducible Example of Tank Game Bug");

        Scene scene = new Scene(graphics, WIDTH, HEIGHT);

        //Reading the keyboard for WASD movement
        scene.setOnKeyPressed(e -> {
            switch (e.getCode()) {
                case W:
                    w = true;
                    break;

                case A:
                    a = true;
                    break;

                case S:
                    s = true;
                    break;

                case D:
                    d = true;
                    break;
            }
        });

        scene.setOnKeyReleased(e -> {
            switch (e.getCode()) {
                case W:
                    w = false;
                    break;

                case A:
                    a = false;
                    break;

                case S:
                    s = false;
                    break;

                case D:
                    d = false;
                    break;
            }
        });

        stage.setScene(scene);
        stage.show();

        AnimationTimer timer = new AnimationTimer() {
            @Override
            public void handle(long now) {
                //Seeing if the player intersects a bullet line
                for (int i = 0; i < bulletLines.length; i++) {
                    if (player.getBoundsInParent().intersects(bulletLines[i].getBoundsInParent())) {
                        bulletLines[i].setStroke(Color.RED);
                    } else {
                        bulletLines[i].setStroke(Color.BLACK);
                    }
                }

                //For moving the player using WASD
                //Diagonals move the player faster in this example
                double x = 0.0;
                double y = 0.0;

                if (w) {
                    y = -1.4;
                }

                if (a) {
                    x = -1.4;
                }

                if (s) {
                    y = 1.4;
                }

                if (d) {
                    x = 1.4;
                }

                player.setTranslateX(player.getTranslateX() + x);
                player.setTranslateY(player.getTranslateY() + y);
            }

        };
        timer.start();
    }

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

谢谢你抽出时间。

暂无答案!

目前还没有任何答案,快来回答吧!

相关问题