使用Java,Slick2D和Tiled Map Editor进行碰撞检测

时间:2015-11-28 03:26:00

标签: java loops collision-detection slick2d tiled

我一直坚持碰撞检测以及如何处理它很长一段时间。我需要帮助了解如何使用Tiled地图编辑器进行碰撞检测。我解析并显示TMX文件,播放器,相机和键盘移动。我不确定怎么做碰撞。我的地图有2层,一层用于草和瓷砖,你可以走,另一层是objectLayer。我见过有人说我应该遍历对象层中的所有图块并为它们指定矩形。我不知道该怎么做,而且我正在寻找一些见解。

我的主要问题是:如何遍历我的图层并获取所有图块并为其指定矩形。

游戏类:

    public class Game extends BasicGameState {

Player player;
Camera cam;
Map map = new Map();

public void init(GameContainer container, StateBasedGame sbg) throws SlickException {
    map.init();
    cam = new Camera(0, 0);
    player = new Player(new Image("res/textures/player.png"), container.getWidth() / 2, container.getHeight() / 2, 32, 32);
}

public void update(GameContainer container, StateBasedGame sbg, int delta) throws SlickException {
    cam.tick(player);
    player.update(container, delta, map);
}

public void render(GameContainer container, StateBasedGame sbg, Graphics g) throws SlickException {
    g.translate(-cam.getX(), -cam.getY());
        map.render();
        player.render(g);
    g.translate(cam.getX(), cam.getY());
}

public int getID() {
    return 1;
}

}

玩家等级:

    public class Player {

float x, y;

int width, height;
double velX = 0.4;
double velY = 0.4;

Image img;

public Player(Image img, float x, float y, int width, int height) {
    this.img = img;
    this.x = x;
    this.y = y;
    this.width = width;
    this.height = height;
}

public void init() throws SlickException {

}

public void update(GameContainer container, int delta, Map map) {
    Input input = container.getInput();

    if (input.isKeyDown(Input.KEY_D)) x += velX;
    if (input.isKeyDown(Input.KEY_A)) x -= velX;
    if (input.isKeyDown(Input.KEY_W)) y -= velY;
    if (input.isKeyDown(Input.KEY_S)) y += velY;

}

public void render(Graphics g) {
    //g.scale(-2, -2);
    g.drawImage(img, x, y);
}

public float getX() {
    return x;
}

public float getY() {
    return y;
}

}

地图类:

    public class Map {

TiledMap map;

public void init() throws SlickException {
    map = new TiledMap("res/map/zenith.tmx");
}

public void render() throws SlickException {
    map.render(0, 0);
}

}

2 个答案:

答案 0 :(得分:2)

我不太熟悉获取磁贴的方法,但它肯定在Javadoc中。 http://slick.ninjacave.com/javadoc/

为了检查与玩家的碰撞,你需要改变你的动作以检查玩家的新位置是否会发生碰撞,否则你会被卡在上面。

public void update(GameContainer container, int delta, Map map) {
    Input input = container.getInput();
    float dx = 0, dy = 0;
    // add to dx and dy instead of moving the player straight away.
    if (input.isKeyDown(Input.KEY_D)) dx += velX;
    if (input.isKeyDown(Input.KEY_A)) dx -= velX;
    if (input.isKeyDown(Input.KEY_W)) dy -= velY;
    if (input.isKeyDown(Input.KEY_S)) dy += velY;
    // here we check the collisions, you can fiddle with this if statement and it'll behave differently.
    if(dx != 0 || dy != 0){
        if(map.checkCollision(x+dx,y+y){
           x+=dx;
           y+=dy;
        }
    }
}

至于检查碰撞本身,你需要在地图类中使用一个新方法,为玩家创建一个矩形,并检查地图类中保存碰撞的2D数组。您可以在地图初始化时填充此数组,方法是通过您需要的图层循环Tiled地图,并检查图块是否与getTile(x,y)冲突。如果图块具有正确的碰撞属性,则在2D阵列中的该位置创建一个矩形,如下所示:

collisionArray[x][y] = new Rectangle(x,y,TILEWIDTH,TILEHEIGHT);

您现在可以检查

中的碰撞
map.checkCollision(x,y)

并使用

为玩家创建一个矩形
Rectangle player = new Rectangle(x,y,PLAYERWIDTH,PLAYERHEIGHT);

将所有这些放在一起你可以检查碰撞阵列中任何一个瓦片的交叉点,如前面提到的那样.Intersect(r)和map.collision可以返回真实的玩家,该玩家应该停止玩家的移动。

我希望这不是太复杂,javadoc非常有用,Kevin Glass写了一个关于用2D阵列检查碰撞的事情,它有不同的碰撞盒大小。 http://www.cokeandcode.com/main/tutorials/tile-maps/

答案 1 :(得分:1)

好的,现在我在checkCollision()

中得到一个空指针异常
public void assignRectangles() {
    int objectLayer = map.getLayerIndex("objectLayer");
    for (int x = 0; x < map.getWidth(); x++) {
        for (int y = 0; y < map.getHeight(); y++) {
            if (map.getTileId(x, y, objectLayer) == 1){
                collisionArray[x][y] = new Rectangle(x * 32, y * 32, 32, 32);
            }
        }
    }
}

public boolean checkCollision(float x, float y) {
    for (int j = 0; j < collisionArray.length; j++) {
        for (int i = 0; i < collisionArray[j].length; i++) {
            if (collisionArray[j][i].getX() == x || collisionArray[j][i].getY() == y) {
                return false;
            }
        }
    }
    return true;
}

我把它放在它说if的行上(collisionArray [j] [i] .getX()== x || collisionArray [j] [i] .getY()== y)

不知道为什么我会得到它