I am currently working on a 2d rpg game like final fantasy 1-4. Basically, my tiled map can be loaded and the sprite can walk freely on the map.
How do I handle collisions with tiled map?
I have created three separate tile layers. "Background Layer", "Collision Layer", "Overhead Layer" and I am not sure if this is useful or not..
Edit: I have now created an object layer for collisions with rectangles over the areas I wanted the sprite to collide.
Any help is greatly appreciated. Thank you!
This is my current code
MapObjects collisionObjects = (GameAssets.mainTiledMap).getLayers().get("CollisionLayer").getObjects();
int tileWidth = 16;
int tileHeight = 16;
for (int i = 0; i < collisionObjects.getCount(); i++) {
RectangleMapObject obj = (RectangleMapObject) collisionObjects.get(i);
Rectangle rect = obj.getRectangle();
rect.set(GamePlayer.x, GamePlayer.y, 16,16);
Rectangle rectobject = obj.getRectangle();
rectobject.x /= tileWidth;
rectobject.y /= tileHeight;
rectobject.width /= tileWidth;
rectobject.height /= tileHeight;
if(rect.overlaps(rectobject)) {
GamePlayer.ableToMove = false;
}
}
In my game i have a 2D int array walls[][]
, where i store the information about the Tiles. For me 0 is no wall, so i can go throught. All other numbers repressent some special walltypes, wtih which i have to handle collisions. To detect if a collision happens i do something like this:
if (yMov > 0) {
int leftX = (int)(position.x - width/2); // The leftmost point of the Object.
int rightX = (int)(position.x + width/2); // The rightmost point of the Object.
int newMaxY = (int)((position.y * yMov * currentSpeed * delta) + height/2);
if (walls[leftX][newMaxY] != 0 || walls[rightX][newMaxY] != 0)
// Collision in positive y-Direction.
Notes:
Integer
presentation of their position.x
and position.y
. yMov
describes the percntual value of the movement in y-Direction. So if you go 45° to the right, up you have yMov = 0.5
, xMov = 0.5
. Left up would be yMov = 0.5
, xMov = -0.5
. yMov < 0
, xMov > 0
, xMov < 0
. EDIT: I try to explain it better: You have a Sprite
defined by his center point: position.x
, position.y
and his size: size.x
, size.y
(width and height). Now think about the case, you run to the right. In this case you can never collide with a tile at your left side. Also if you are moving to the right you can not collide with tiles above or under you. So there is only 1 Tile to check: The Tile to your right. Also you can only collide with the Tile to your right, if the right part of your sprite ( position.x + size / 2
) moves far enought. In case you are moving in between 2 tiles in y direction you have to check the Tile at your newX
postition and your upperY
(position.y + size.y / 2) and lowerY
(position.y - size.y / 2).
To give you a picture of what i am using: Collision detection . Look at the 3rd picture, with this description:
The above image gives us 2 candidate cells (tiles) to check if the objects in those cells collide with Bob.
This collision there is for platformers, where you have a gravity, so you have to check the Tile under you cause of that. In top down games this is not the case. I am not using exactly this method, but the picture shows, what i am doing.
If you have any other questions feel free to ask.
I really don't recommend using rectangles. Instead, what I did in my own game is:
In the code, when you process the player movement, write something like this pseudo code:
try { cell = collisionLayer.getCell((int) (x / collisionLayer.getTileWidth()), (int) (y / collisionLayer.getTileHeight())); } catch (Exception e) { e.printStackTrace(); } if (cell.getTile().getProperties().containsKey("blocked")) { blocked = true; }
where x and y are the position of the cell you want to check. And then if blocked = true, do not move the player. If blocked = false, move the player.
I might have been unclear in this answer, if I was, please don't hesitate to send me a message or check this awesome tutorial by dermetfan .
我假设您有一个处理运动阶段的方法,如果是这样,我过去所做的方法是,在确定运动方向后,检查矩形碰撞层,检查位置是否相交边界之一然后返回/运行一种方法,但是您要处理该方法,即玩家死亡,或者玩家位置不变。
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.