LibGDX - Tiled collisions?

I’ve been looking at making collisions for my game using Tiled but I can’t seem to find a good or straight answer. There seems to be some sort of debate between in ways to complete collisions and it’s confusing me.

Using Slick2D is was fairly straight forward and was wondering if there was a similar way I could achieve collisions in the same way in LibGDX? If not, what is the best way I could achieve collisions for a simple side scroller game like Mario with coins etc

Thanks :slight_smile:

Tiled is a map editor; it modifies the world. What it does has nothing to do with how you use it (like collision).

Kevglass has done a tutorial on this, and it will not matter if it is in GDX, as it will work in the same way. See the ‘collision logic’ section. You can find this here.

when using slick, you can add tile properties to the tiles… so just make a “blocked” property and add the value to “true” to the tiles that should be blocked… then make an if statement and if the property is blocked make the player not move… and vice-versa…

Well, slick does that. Tiled just modifies tilemap files.

Just modify the tutorial to your own needs.

You’re probably having issues is there really is no one single definitive way to do collision detection. I think the most common method is using rectangles and checking intersect. It’s pretty straight forward.

A simple way would be, assuming you’re using TilEd. I assume Lib has someway to fetch tile properties. I can’t imagine why it wouldnt.

  1. Inside TilEd, right click on the sprite(s) you want to be blockable, click properties and add blocked = true.
  2. Inside your program, run a for loop through your entire map, checking if that tile has that property
  3. If found, create a rectangle there and stick it in an ArrayList.
  4. Have the player have a rectangle as well, that’s centered on the player at all times.
  5. If your player’s rectangle intersects with the map’s, a collision has happened. Stop moving, bounce back, or whatever you want to do.

I explained this to someone else a while back in a lot more detail here, but he was using Slick2d. The concept is the same on either library though. You just need to tweak the source code a bit to use some of Lib’s equivalent methods/classes;
http://www.java-gaming.org/topics/java-slick2d-gettileproperty-returns-true-when-it-shouldn-t/32902/msg/309373/view.html#msg309373
(if it doesn’t bounce you to the right reply, it’s reply #19)

I wasn’t keen on the whole get property thing, so I had a texture tiled that was a big B, had a new image layer and textured the transparent B on what I wanted blocked. Then when I loaded a level I went through all the tiles and stored true/false into an array ‘blocked[][]’. Then when you move into a new tile (dividing position by tilewidth and height) if its blocked… no move.

Thats the more classic method of doing it, instead of using properties just have a second map layer with special tiles like “B” for blocked then just loop through that layer to find your collision areas.

Downside is if you forget to “block” something that should be blocked, your character will be able to walk through the object. Of course, depending on your game design that could also be a good thing.

Thank you all for your answers, I have got somewhere but I am still having a few issues.

I am using this code here at the moment and it works for what I need right now:

 for (y = 0; y < layer.getHeight(); y++) {
	        for (x = 0; x < layer.getWidth(); x++) {
	            if (layer.getCell(x, y) != null && layer.getCell(x, y).getTile().getProperties().containsKey("Blocked")) {
	            	 System.out.println("Test");
	            	}
	           }
	     }

I am using a layer that holds all the tiles that can be collided and in this case, the layer has 6 32*32 tiles. This causes “Test” to print 6 times and ignore the empty tiles which is good. I just need to figure a way to get collisions from the player and stop player movement now, likely using the rectangle method that Ray suggest.

EDIT: I’m also not sure how to make the rectangles relevant to tile positions

Detecting collisions is actually not that hard. The problem is how you resolve the collisions. Just stopping the movement will most likely get the player stuck in the wall. If you are using libgdx you could save the time on implementing something yourself and use box2d to do the heavy lifting for you. A friend has started using it for his 2d oldschool rpg (something like the first zelda games) and it works quite well. Cool part is that you can use an object layer in tiled and simply draw the collision boxes with rectangles / polygons and import them into box2d. I have done this once by hand, but since then I learned that libgdx has a class to do exactly that.

If you just want to make a simple collision detection, you could use two Rectangle (com.badlogic.gdx.math) instances. Use a loop to cycle through each neighbour tile and check if the entity intersects with it. If the checked neighbour is a wall, assign size and position of the entity (player) you want to check to the first rectangle, and the same for the wall to the second rentangle. Then you can call rect1.intersects(rect2) to check, if they overlap. Just store the walls that have intersected for later resolution.
To resolve this, you can loop through the walls that have intersected and move the player one pixel away from the walls. Do this until the player isn’t stuck anymore.

This is a very basic method of doing it and only will work, if the walls are full tiles and the entity (collision box) is smaller than a tile. I’d still recommend using box2d though :wink:

As for your problem, usually you need the tile size and the x and y position in the layer to calculate the pixel based position. I modified your code to show how to get the x and y positions of a tile.


float tileWidth = layer.getTileWidth();
float tileHeight = layer.getTileHeight();
for (int y = 0; y < layer.getHeight(); y++) {
	for (int x = 0; x < layer.getWidth(); x++) {
		Cell cell = layer.getCell(x, y);
		if (cell != null) {
			TiledMapTile tile = cell.getTile();
			if (tile != null && tile.getProperties().containsKey("Blocked")) {
				float tx = x * tileWidth;
				float ty = y * tileHeight;
			}
		}
	}
}

Thank you for your solution and your insight into Box2D. I will see if I can find some good tutorials/documentation on Box2D :)! I am still new to LibGDX but the more I become comfortable with it, I am sure it will become easier to pickup

I also understand what my issue was, regarding the tileWidth and tileHeight so hopefully I won’t come across this issue again, ty :slight_smile:

If you look into box2d I think the most valuable help to start is the main manual, even if the code is slightly different (c++ instead of java).

http://box2d.org/manual.pdf

The basics of box2d are very well explained. When you think you understand what is going on, you can have a look at the libgdx wiki on how to setup box2d for libgdx => https://github.com/libgdx/libgdx/wiki/Box2d
Then you can try implementing the examples from the manual.

Just so you don’t mess up the game, I would create a new test project, where you try out your first steps with box2d and when you think you understand what you are doing, you can integrate it into your game.

I will actually do that now :slight_smile: I just managed to get my collison working! Yay. It was a long process but I learnt a ton of stuff which is great! :slight_smile:

Thank you for the menu as well!

Hey guys, got another question related to this topic.

In slick2D I made it so the player simply couldn’t move if the tileID was a specific ID and this worked really well. In LibGDX it’s different and everything works great regarding the rectangles being drawn over the tiles that have specific properties but I have the issue with the player getting stuck in the wall.

I was wondering how I should go about detecting what side of the player collides with the rectangle and then applying the correct ‘bounce’ back. Not sure if this is the best way but it seems to make sense to me. Collision detection is really new to me, especially Tiled maps.

P.S. I looked into Box2D and I am sooooo going to learn about it :slight_smile: looks really near and I love the look of Box2D lights. Once I have my main LibGDX stuff out of the way, i’ll explore it some more

You need to compare the coordinates of the colliding wall and on the coordinates of your player (the center of your player sprite). Then you just have to compare x and y values of both.

If the wall x is smaller, it is to the left. If the wall x is higher than player x, then it is to the east.

The same goes for y. It wall y < player y the wall is to the south.

Then just move the player in the opposite direction until the collision has been resolved.

Thanks a bunch! You taught me something new :smiley: haha. Thanks for all your help guys, you have helped me learn a lot about collision detect and I feel that I understand for loops much better, they have not always been my strongest point

I used this code to solve it: The player seems to bounce off the walls pretty, is this correct or am I missing something? I’m personally fine with it but thought it might annoy others :stuck_out_tongue:

for(int i = 0; i < CollisionArray.size(); i++){ // Loop through the array and check if any collisions happen
			if(player.bounds.overlaps(CollisionArray.get(i)) 
				
				if(CollisionArray.get(i).getX() > player.getX()){ // Gets the x value of the colliding rectangle here and check it's value
					player.setX(20); // Testing if it works
				}
				break;
			}
	    }

Looks like you found a solution :). Just wanted to mention the Box2D methods because I use it and it works well. You could create a static body for each tile if the worlds are not extremely large. Or you could manually create objects in Tiled that correspond to collision regions, and use Box2D to generate static bodies there. This allows for more physics options in the future if you intend to use Box2D.

Oh, thank you :slight_smile: that gives me some insight into how I could deal with Box2D and collisions. I’m planning on finishing most of this game and then will start a new project with Box2D and Box2D lights! :slight_smile: want to increase my skills with each project