如何使用Slick2D使用tile属性检测和处理冲突?

我试图在Slick2D基础上设置一个基于地图的碰撞检测。 我目前在地图上有两个图层,一个背景图层和一个碰撞图层。 碰撞层有一个“阻塞”属性的瓦片,画在玩家不能走的区域上。 我已经浏览了Slick文档,但不明白如何读取tile属性并将其用作碰撞检测的标志。

我的“移动”播放器的方法有些不同,可能会影响碰撞的处理方式。 玩家总是停留在同一个地点,而不是更新玩家在窗口上的位置,更新地图渲染的x和y。 我正在通过限制播放器的移动来处理与对象的碰撞,当它的hitbox与对象的hitbox相交时。 例如,玩家击中对象右侧的代码如下所示:

if(Player.bounds.intersects(object.bounds)&&(Player.x<=(object.x+object.width+0.5))&&Player.isMovingLeft){ isInCollision=true; level.moveMapRight(); } else if(Player.bounds.intersects(object.bounds)&&(Player.x<=(object.x+object.width+0.5))&&Player.isMovingRight){ isInCollision=true; level.moveMapRight(); } else if(Player.bounds.intersects(object.bounds)&&(Player.x<=(object.x+object.width+0.5))&&Player.isMovingUp){ isInCollision=true; level.moveMapRight(); } else if(Player.bounds.intersects(object.bounds)&&(Player.x<=(object.x+object.width+0.5))&&Player.isMovingDown){ isInCollision=true; level.moveMapRight(); } 

并在关卡的更新代码中:

 if(!Player.isInCollision) Player.manageMovementInput(map, i); 

但是,这种方法仍然有一些错误。 例如,当从右侧击中对象时,玩家将向上和向左移动,通过对象剪切并卡在其hitbox内。 如果有更有效的方式来处理这个,任何意见将不胜感激。

首先,要从Tiles获取属性,需要在实例化TiledMap时循环访问它们。 不要试图在更新块中读取它们,因为这是一个非常慢的操作。

在你的Map类中,添加两个属性:

  / /这将保持阻止的瓷砖列表
 private boolean blocked [] [];

 //对于碰撞检测,我们有一个可以用来testing的矩形列表
 private ArrayList <Rectangle> blocks;

然后,在构造函数中,可以读取Tiles属性:

 // This will create an Array with all the Tiles in your map. When set to true, it means that Tile is blocked. blocked = new boolean[this.getWidth()][this.getHeight()]; // Loop through the Tiles and read their Properties // Set here the Layer you want to Read. In your case, it'll be layer 1, // since the objects are on the second layer. int layer = 1; for(int i = 0; i < this.getWidth(); i++) { for(int j = 0; j < this.getHeight(); j++) { // Read a Tile int tileID = getTileId(i, j, layer); // Get the value of the Property named "blocked" String value = getTileProperty(tileID, "blocked", "false"); // If the value of the Property is "true"... if(value.equals("true")) { // We set that index of the TileMap as blocked blocked[i][j] = true; // And create the collision Rectangle blocks.add(new Rectangle((float)i * tileSize, (float)j * tileSize, tileSize, tileSize)); } } } 

被阻塞的[] []数组将存储哪个Tiles被阻塞。 使用这个作为进一步的参考,而不是再次阅读地图属性。

关于处理检测:

如果你想检查碰撞,只需循环块列表,并检查球员是否与他们相交。

 boolean isInCollision = false; for(Rectangle ret in yourTiledMap.getBlocks()) { if(player.bounds.intersects(ret.bounds)) { isInCollision = true; } }