1

我真的可以使用一些帮助来为我的游戏找到可行的解决方案。我的游戏快完成了,但我游戏中的墙仍然无法正常工作。

我试图在互联网上为这个问题找到解决方案,但我仍然没有找到一种简单的方法来在矩形与墙壁(另一个矩形)碰撞之前停止它。

现在我已经实现了玩家矩形和墙壁矩形之间的碰撞检测,然后停止它移动,但是当它撞到时它会卡在墙内。

希望它在之前停止,所以它仍然可以移动。到目前为止我所做的代码在这里:

吃豆人类

public class Pacman {

private String pacmanup = "pacmanup.png";
private String pacmandown = "pacmandown.png";
private String pacmanleft = "pacmanleft.png";
private String pacmanright = "pacmanright.png";

private int dx;
private int dy;
private int x;
private int y;
private int width;
private int height;
private boolean visible;

private Image imageup;
private Image imagedown;
private Image imageleft;
private Image imageright;

public Pacman() {

    ImageIcon i1 = new ImageIcon(this.getClass().getResource(pacmanup));
    imageup = i1.getImage();

    ImageIcon i2 = new ImageIcon(this.getClass().getResource(pacmandown));
    imagedown = i2.getImage();

    ImageIcon i3 = new ImageIcon(this.getClass().getResource(pacmanleft));
    imageleft = i3.getImage();

    ImageIcon i4 = new ImageIcon(this.getClass().getResource(pacmanright));
    imageright = i4.getImage();

    width = imageup.getWidth(null);
    height = imageup.getHeight(null);
    visible = true;
    x = 270;
    y = 189;

}

public int getDx() {
    return dx;
}

public void setDx(int dx) {
    this.dx = dx;
}

public int getDy() {
    return dy;
}

public void setDy(int dy) {
    this.dy = dy;
}

public int getX() {
    return x;
}

public int getY() {
    return y;
}

public void setX(int x) {
    this.x = x;
}

public void setY(int y) {
    this.y = y;
}

public Image getImageup() {
    return imageup;
}

public Image getImagedown() {
    return imagedown;
}

public Image getImageleft() {
    return imageleft;
}

public Image getImageright() {
    return imageright;
}

public void setVisible(boolean visible) {
    this.visible = visible;
}

public boolean isVisible() {
    return visible;
}

public Rectangle getBounds() {
    return new Rectangle(x, y, width, height);
}

public void move() {

    x += dx;
    y += dy;
}

public void keyPressed(KeyEvent e) {

    int key = e.getKeyCode();

    if (key == KeyEvent.VK_LEFT) {
        dx = -2;
        dy = 0;
    }

    if (key == KeyEvent.VK_RIGHT) {
        dx = 2;
        dy = 0;
    }

    if (key == KeyEvent.VK_UP) {
        dx = 0;
        dy = -2;
    }

    if (key == KeyEvent.VK_DOWN) {
        dx = 0;
        dy = 2; 
    }
}

在这里,我创建了一个 Rectangle getBounds 方法,用于创建 pacman 的矩形并在其上放置图像。

屏障类/墙类

public class Barrier {

private String barrier = "barrier.png";

private int x;
private int y;
private int width;
private int height;
private boolean visible;
private Image image;

public Barrier(int x, int y) {
    ImageIcon ii = new ImageIcon(this.getClass().getResource(barrier));
    image = ii.getImage();      
    width = image.getWidth(null);
    height = image.getHeight(null);
    visible = true;
    this.x = x;
    this.y = y;
}

public int getX() {
    return x;
}

public int getY() {
    return y;
}

public boolean isVisible() {
    return visible;
}

public void setVisible(Boolean visible) {
    this.visible = visible;
}

public Image getImage() {
    return image;
}

public Rectangle getBounds() {
    return new Rectangle(x, y, width, height);
}

这个类也有我用来检测碰撞的 Rectangle getBounds 类。

我展示的最后一个代码是到目前为止我如何进行碰撞检测:

Board 类中的代码

Rectangle r3 = pacman.getBounds();

 for (int j = 0; j<barriers.size(); j++) {
        Barrier b = (Barrier) barriers.get(j);
        Rectangle r4 = b.getBounds();

        if (r3.intersects(r4)) {
            System.out.println("Wall hit");
            pacman.setDx(0);
            pacman.setDy(0);
        }
    }

好吧,我该怎么做,如果 r3 和 r4 之间发生碰撞,我会将 Dx 和 Dy 设置为 0.. 我想找到另一个解决方案,以便它检测碰撞,但我不会卡在墙内,但我不'不知道怎么做:/

希望有人会提供帮助。

4

1 回答 1

3

您可以遵循两种方法。一种丑陋但更容易,另一种需要对你的类进行更深入的重新设计。

1)丑陋/简单的方法

在丑陋的情况下,您在进行碰撞检查之前不断移动您的家伙。只需将您的 pacman 移回未卡住的位置即可。您可以通过反转最后使用的方向来实现:

Board 类中的代码

改变你的反应,以防你发现碰撞:向后走同样的距离。

    if (r3.intersects(r4)) {
        System.out.println("Wall hit, move back");
        pacman.setDx(-pacman.getDx());
        pacman.setDy(-pacman.getDy());
        // Possibly need to call move() here again.
        pacman.move();
        break;
    }

丑陋,但应该工作。
不过,不建议对患有强迫症和心脏病的完美主义者进行编码。

2) 重新设计

在这种方法中,您在进行任何实际移动之前测试吃豆人将占据的位置。如果该点没有进入任何障碍,则真正执行该运动。

Pacman 类中的代码

添加此方法,以便您可以检查与新边界的碰撞。

public Rectangle getOffsetBounds() {
    return new Rectangle(x + dx, y + dy, width, height);
}

Board 类中的代码

// Strip the call to pacman.move() prior to this point.

Rectangle r3 = pacman.getOffsetBounds(); // Check against the candidate position.

for (int j = 0; j<barriers.size(); j++) {
    Barrier b = (Barrier) barriers.get(j);
    Rectangle r4 = b.getBounds();

    if (r3.intersects(r4)) {
        System.out.println("Wall hit");
        pacman.setDx(0);
        pacman.setDy(0);
        // Quit the loop. It's pointless to check other barriers once we hit one.
        break;
    }
}
// Now we're good to move only in case there's no barrier on our way.
pacman.move();

特别是我更喜欢这种方法,但由你来选择最好的方法。

于 2015-01-30T19:42:52.713 回答