java - 碰撞检测 Java 2D Sprite

标签 java 2d collision-detection sprite

因此,我尝试在游戏中实现碰撞检测,但由于某种原因,碰撞无法正常工作。

public class ArenaKeys extends KeyAdapter {
    arenaScreenBuild arena;
    int xPos = 0, playerFace = 4;
    int xPPos = 200, yPPos = 150;
    int pX = 40, pY = 30;
    AttackAshe aAtk = new AttackAshe();

    int[][] mask = new int[400][92];

    @SuppressWarnings("static-access")
    public void keyPressed(KeyEvent e) {
        int keyCode = e.getKeyCode();// Get key pressed
        if (keyCode == e.VK_RIGHT) {
            playerFace = 4;
            xPos += 5;
            pX = (xPos + xPPos) / 5;
            if (checkBoundary(pX, pY) == (false))
                xPos -= 5;
        } else if (keyCode == e.VK_LEFT) {
            playerFace = 3;
            xPos -= 5;
            pX = (xPos + xPPos) / 5;
            if (checkBoundary(pX, pY) == (false))
                xPos += 5;
        } else if (keyCode == e.VK_UP) {
            playerFace = 2;
            yPPos -= 5;
            pY = yPPos / 5;
            if (checkBoundary(pX, pY) == (false))
                yPPos += 5;
        } else if (keyCode == e.VK_DOWN) {
            playerFace = 1;
            yPPos += 5;
            pY = yPPos / 5;
            if (checkBoundary(pX, pY) == (false))
                yPPos -= 5;
        }
        if (keyCode == e.VK_SPACE) {
            aAtk.regArrow(arena.xPosition(), arena.yPosition());
            arena.shoot(playerFace);
            arena.xArrow = xPPos;
            arena.yArrow = yPPos;
        } else if (keyCode == e.VK_ESCAPE)
            System.exit(0);
        arena.moveArena(xPos);
        arena.turnPlayer(playerFace);
        arena.updateScreen(xPPos, yPPos);
    }

    public boolean checkBoundary(int x, int y) {
        Rectangle t1 = new Rectangle(Turret.x, Turret.y, Turret.WIDTH,
                Turret.HEIGHT);
        Rectangle p = new Rectangle(pX, pY, Player.WIDTH, Player.HEIGHT);

        if (t1.intersects(p))
            // if (mask[x][y] == 0)
            return false;
        else
            return true;
    }
    public static class Turret {
        static int x = 168;
        static int y = 40;
        static final int WIDTH = 50;
        static final int HEIGHT = 50;
    }

    public static class Player {
        static final int WIDTH = 25;
        static final int HEIGHT = 25;
    }

    public ArenaKeys(arenaScreenBuild arena) throws Exception {
        this.arena = arena;
    }
}

距离实际炮塔大约 20 个单位, Sprite 无法再进一步移动。即使你走得非常高或非常低, Sprite 也无法到达炮塔上方或下方。

问题似乎在于 Sprite 过早地碰撞到炮塔矩形中,但我不明白这是怎么可能的。我在 168,40 处准确绘制了 50 宽、50 高的炮塔。玩家在移动,因此 x、y 每次都不同,但其尺寸为 25 宽和 25 高。

My Turret

原来的炮塔大约是126x111,但我把它画成50x50

Sample Sprite 25x25

public class arenaScreenBuild extends JPanel implements ActionListener {
    String picPath = "pictures/";
    String[] fileName = { "stageBridge.png", "turret.png", "Ashe.png",
            "regArrow.png", "arenaScreen.png" };
    ClassLoader cl = arenaScreenBuild.class.getClassLoader();
    URL imgURL[] = new URL[5];
    Toolkit tk = Toolkit.getDefaultToolkit();
    Image imgBG, imgTurret, imgPlayer, imgRegArrow, imgBorder;
    Boolean[] ptFunc = new Boolean[3];

    int PLAYER_INITIAL_X = 200, PLAYER_INITIAL_Y = 150;
    int xPos = 0, xPFace = 150, yPFace = 0;
    int xPPos = 200, yPPos = 150;
    int xVal, yVal, xArrow, yArrow, xTemp, yTemp;
    Timer space;
    int counter, facePosition = 1;

    public arenaScreenBuild() throws Exception {
        for (int x = 0; x < 5; x++) {
            imgURL[x] = cl.getResource(picPath + fileName[x]);
        }
        imgBG = tk.createImage(imgURL[0]);
        imgTurret = tk.createImage(imgURL[1]);
        imgPlayer = tk.createImage(imgURL[2]);
        imgRegArrow = tk.createImage(imgURL[3]);
        imgBorder = tk.createImage(imgURL[4]);
        for (int x = 0; x < 3; x++)
            ptFunc[x] = true;

        space = new Timer(100, this);

    }

    public void updateScreen() {
        repaint();
    }

    public void moveArena(int x) {
        xPos = x;
    }

    public void updateScreen(int x, int y) {
        xPPos = x;
        yPPos = y;
        repaint();
    }

    public boolean arrow() {
        return (true);
    }

    public void turnPlayer(int face) {
        if (face == 4) {
            xPFace = 150;
        } else if (face == 3) {
            xPFace = 100;
        } else if (face == 2) {
            xPFace = 50;
        } else if (face == 1) {
            xPFace = 0;
        }
        if (yPFace == 50)
            yPFace = 0;
        else if (yPFace == 0)
            yPFace = 50;
    }

    public void paintComponent(Graphics g) {
        g.drawImage(imgBG, 10, 30, 610, 490, xPos, 0, xPos + 600, 460, this);

        g.drawImage(imgTurret, 850 - xPos, 200, 950 - xPos, 300, 0, 0, 126,
                110, this);
        g.drawImage(imgTurret, 1350 - xPos, 200, 1450 - xPos, 300, 0, 0, 126,
                110, this);

        g.drawImage(imgPlayer, xPPos, yPPos, 50 + (xPPos),
                50 + (yPPos), xPFace, yPFace, xPFace + 50, yPFace + 50, this);

        if (counter <= 5000 && counter > 0)
            g.drawImage(imgRegArrow, xArrow, yArrow, this);

        g.drawImage(imgBorder, 0, 0, 620, 600, 0, 0, 620, 600, this);

        g.setColor(Color.WHITE);
        g.drawString("x:" + (xPPos + xPos), 535, 525);
        g.drawString("y:" + yPPos, 535, 545);
    }

    public int xPosition() {
        xVal = xPPos + xPos;
        return (xVal);
    }

    public int yPosition() {
        yVal = yPPos;
        return (yVal);
    }

    public void shoot(int i) {
        facePosition = i;
        xTemp = xPosition();
        yTemp = yPosition();
        space.start();
    }

    public void actionPerformed(ActionEvent e) {
        counter++;

        if (facePosition == 4) {
            if (counter <= 5000) {
                xArrow += 50;
            }
        }

        else if (facePosition == 3) {
            if (counter <= 5000) {
                xArrow -= 50;
            }
        }

        else if (facePosition == 2) {
            if (counter <= 5000) {
                yArrow -= 50;
            }
        }

        else if (facePosition == 1) {
            if (counter <= 5000) {
                yArrow += 50;
            }
        }

        if (xArrow == (xTemp + 100)) {
            counter = 0;
            space.stop();
        }

        updateScreen();
    }
}

最佳答案

事实证明我的 x 位置值是错误的。另外,由于我以前的边界代码,仍然有它的残余,这让我很困惑,因此不允许我尽早看到问题。

对于任何想知道如何制作碰撞检测边界的人,只需制作 2 个矩形并使用

Rectangle rect1 = new Rectangle(topLeftX, topLeftY, rectangleWidth,rectangleHeight);
Rectangle rect2 = new Rectangle(topLeftX, topLeftY, rectangleWidth, rectangleHeight);
if (rect1.intersects(rect2))
//enter code to do if it intersects here

关于java - 碰撞检测 Java 2D Sprite,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14106260/

相关文章:

java - iText 未生成预期的 PDF 格式

java - 如何在Spring Security中使用过滤器以及在过滤器中开发Authentication

collision-detection - 如何测试两个移动的2D定向边界框的碰撞?

javascript - 具有重力的2D碰撞检测-JavaScript

Java 2D 游戏编程-SpriteSheet 动画

android - 让一个球在另一个圆圈内滚动

java - 尝试让 ANTLR 语法遵循 AND/OR 语句

java - 握手完成后服务器关闭套接字

WPF:调整圆的大小,保持中心点而不是 TopLeft?

java - 如何根据二维网格上的路径为线条设置不同的颜色