【发布时间】:2014-04-09 00:38:10
【问题描述】:
我正在用 java 制作 2d rpg 游戏,但遇到了问题。我可以让玩家在舞台上移动,舞台上也有岩石、树木、墙壁等。我不知道如何检测碰撞并使其到达玩家无法穿过物体的地方。读取地图文件并在画布上绘制图像的代码如下:
public void loadLevel(BufferedImage levelImage){
tiles = new int[levelImage.getWidth()][levelImage.getHeight()];
for (int y = 0; y < h; y++) {
for (int x = 0; x < w; x++) {
Color c = new Color(levelImage.getRGB(x, y));
String h = String.format("%02x%02x%02x", c.getRed(),c.getGreen(),c.getBlue());
switch(h){
case "00ff00"://GRASS Tile - 1
tiles[x][y] = 1;
break;
case "808080"://Stone -2
tiles[x][y] = 2;
break;
case "894627"://Dirt -3
tiles[x][y] = 3;
break;
case "404040"://Rock on Grass -4
tiles[x][y] = 4;
break;
case "00b700"://Tree -5
tiles[x][y] = 5;
break;
case"000000"://Wall -6
tiles[x][y] = 6;
break;
case "cccccc"://Rock on stone -7
tiles[x][y] = 7;
break;
default:
tiles[x][y] = 1;
System.out.println(h);
break;
}
}
}
}
而播放器类如下:
public class Player {
private int x,y;
public int locx,locy;
private Rectangle playerR;
private ImageManager im;
public boolean up =false,dn = false,lt=false,rt=false,moving = false,canMove = true;
private final int SPEED =2;
public Player(int x, int y, ImageManager im){
this.x = x;
this.y = y;
this.im = im;
locx = x;
locy = y;
playerR = new Rectangle(x,y,16,16);
}
public void tick(){
if (up) {
if(canMove){
y -= SPEED;
locx = x;
locy = y;
playerR.setLocation(locx, locy);
moving = true;
}
else{
y += 1;
canMove=true;
}
}
if (dn) {
y +=SPEED;
locx = x;
locy = y;
moving = true;
}
}
if (lt) {
x -= SPEED;
locx = x;
locy = y;
moving = true;
}
if (rt) {
x+=SPEED;
locx = x;
locy = y;
moving = true;
}
}
if(moving){
System.out.println("PLAYER\tX:"+locx+" Y:"+locy);
moving = false;
}
}
public void render(Graphics g){
g.drawImage(im.player, x, y, Game.TILESIZE*Game.SCALE, Game.TILESIZE*Game.SCALE, null);
}
}
我真的不知道如何进行碰撞,但是我用谷歌搜索了它,人们说要为玩家和玩家应该碰撞的所有对象制作一个矩形,并且每次玩家移动时,移动玩家的矩形.这是正确的方法吗?
编辑编辑编辑编辑
碰撞为真时的代码:
if (rt) {
x+=SPEED;
locx = x;
locy = y;
playerR.setLocation(locx, locy);
for(int i = 0;i<Level.collisions.size();i++){
if(intersects(playerR,Level.collisions.get(i))==true){
x-=SPEED;
locx = x;
playerR.setLocation(locx, locy);
}
}
moving = true;
}
相交方法如下:
private boolean intersects(Rectangle r1, Rectangle r2){
return r1.intersects(r2);
}
【问题讨论】:
-
一般来说是的,最简单的 2D 碰撞检测是用矩形或圆形物体完成的。这些需要附加到屏幕上移动的对象上,以便计算碰撞检测。看看 JBox2D,它是一个开源物理引擎。 jbox2d.org
-
有没有办法在不使用任何外部引擎或任何东西的情况下做到这一点?
-
当然可以。看起来您已经开始使用 Player。确保每次玩家移动时更新矩形。您还需要将一个矩形添加到您可能想知道玩家是否与之发生碰撞的任何地方。最后,每一帧都需要遍历所有可碰撞的对象,并查看玩家的矩形是否与对象的矩形相交。这是一个非常粗略的算法,但它是一个很好的起点。
-
如何在第一种方法中为每个“草地上的岩石”制作一个矩形?我想将矩形存储在 ArrayList 中,但我不确定我将如何进行编码?或者如果有更好的方法。另外,为了检查碰撞,我是否会在 Player 类的 tick 方法开始处使用 for 循环,如果发生碰撞,将 CanMove 设置为 false?最后一件事,为了检查碰撞,我使用 .intersects 对吗?
-
保存所有可碰撞矩形的 ArrayList 是完全可以接受的。在创建对象时添加它们。至于检测碰撞,请像往常一样移动播放器。如果发生碰撞,请将玩家向后移动。您必须移动玩家以确定是否存在碰撞。如果您想变得花哨,只需将玩家向后移动足够多,这样就不会再发生碰撞。使用 Rectangle.intersects() 会起作用,或者如果您想自己动手学习它是如何工作的,请创建一个新方法
private boolean intersects(Rectangle r1, Rectangle r2)
标签: java collision-detection bufferedimage game-physics