Java 中的矩形墙碰撞
Rectangle Wall collision in Java
我真的需要一些帮助才能为我的游戏找到可行的解决方案。
我的游戏快完成了,但我游戏中的墙仍然没有正常工作。
我试图在互联网上找到解决这个问题的方法,但我仍然没有找到一种简单的方法来在矩形与墙(另一个矩形)碰撞之前停止它。
现在我已经实现了播放器矩形和墙矩形之间的碰撞检测,然后停止它移动,但是当它撞击时它会卡在墙内。
想让它刚才停下来,这样它还能动。到目前为止我完成的代码在这里:
吃豆子Class
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 的矩形并在其上放置图像。
屏障class/墙class
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);
}
这个 class 也有我用来检测碰撞的 Rectangle getBounds class。
我展示的最后一个代码是到目前为止我是如何进行碰撞检测的:
板内代码class
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..我想找到另一个解决方案以便它检测碰撞但我不会卡在墙,但我不知道如何:/
希望有人能帮忙。
您可以采用两种方法。一个丑陋但更容易,另一个需要对您的 classes 进行更深入的重新设计。
1) Ugly/Simple 方法
在丑陋的那个中,你在进行碰撞检查之前一直移动你的家伙。只需将吃豆子移回未卡住的位置即可。您可以通过反转最后使用的方向来实现:
板内代码class
如果发现碰撞,改变您的反应:向后走同样的距离。
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 将占据的位置。如果那个点没有进入任何障碍,那么就真正地执行这个动作。
Pacman 内的代码class
添加此方法,以便您可以检查新边界的碰撞。
public Rectangle getOffsetBounds() {
return new Rectangle(x + dx, y + dy, width, height);
}
板内代码class
// 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();
我特别喜欢这种方法,但是您可以选择最好的方法。
我真的需要一些帮助才能为我的游戏找到可行的解决方案。 我的游戏快完成了,但我游戏中的墙仍然没有正常工作。
我试图在互联网上找到解决这个问题的方法,但我仍然没有找到一种简单的方法来在矩形与墙(另一个矩形)碰撞之前停止它。
现在我已经实现了播放器矩形和墙矩形之间的碰撞检测,然后停止它移动,但是当它撞击时它会卡在墙内。
想让它刚才停下来,这样它还能动。到目前为止我完成的代码在这里:
吃豆子Class
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 的矩形并在其上放置图像。
屏障class/墙class
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);
}
这个 class 也有我用来检测碰撞的 Rectangle getBounds class。
我展示的最后一个代码是到目前为止我是如何进行碰撞检测的:
板内代码class
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..我想找到另一个解决方案以便它检测碰撞但我不会卡在墙,但我不知道如何:/
希望有人能帮忙。
您可以采用两种方法。一个丑陋但更容易,另一个需要对您的 classes 进行更深入的重新设计。
1) Ugly/Simple 方法
在丑陋的那个中,你在进行碰撞检查之前一直移动你的家伙。只需将吃豆子移回未卡住的位置即可。您可以通过反转最后使用的方向来实现:
板内代码class
如果发现碰撞,改变您的反应:向后走同样的距离。
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 将占据的位置。如果那个点没有进入任何障碍,那么就真正地执行这个动作。
Pacman 内的代码class
添加此方法,以便您可以检查新边界的碰撞。
public Rectangle getOffsetBounds() {
return new Rectangle(x + dx, y + dy, width, height);
}
板内代码class
// 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();
我特别喜欢这种方法,但是您可以选择最好的方法。