LIbgdx: Tips on best practices for tilemap (Polygon?) collision detection

Hi,

I created a map with Tiled for a side scrolling space shooter consisting of 32x32 tiles and I’m looking for a way to set up collision detection for my space ship with parts of the background.
The standard method of giving tiles a value (like “blocked”) for those specific tiles that my ship collides with doesnt work very well here because the collision detection would be very unprecise.
For example with some tiles i want my ship only to collide with the rocky part (which is only half of the tile) and not collide with the other part.

So i thought about drawing polylines in my map over the parts where i want my ship to collide thinking I could use this polyline mapobjects to check if it overlaps my ship (just like you would with a standard rectangle overlap collision check).

There was a post I read here where someone used Intersector to check if 2 Convex polygons intersect:
http://www.java-gaming.org/index.php?topic=28930

First I thought that might be a way to do it but then i figured that my objects arent Polygons & they arent convex so I think i probably wouldnt be able to do it this way.

Does anyone have tips on how i should set up my Collision Detection?
Is it possible using polyline map objects? Or should I do it totally different?

Here is an Image of what a part of my map looks like and how i would want to draw my polyline boundries…

So what you need is the Separating Axis Theorem (discussed in the thread you linked). This solution only applies to convex polygons (yours are concave) so you will have to “triangulate” your polygons, or split them up into triangles. You can do this manually or you can find an algorithm to do this for you (Googling gives many results).

Interesting idea, but it looks pretty complex and time intensive though.

I also came up with another idea just now.
Tiled also has a possibilitie to add Image Layers. So if i can find a way to convert my map made in tiled to an Image files I could create a new map; add the image file to to image layer and create a tile layer with just one small tile block. Say 4x4 or so.
I could then give that one tile a value like blocked, use it to outline all the image’s areas where i want my ship to collide with the background & in my collision detection method I can check if my ship is overlapping with that tile.

Have to figure out how i convert my tilemap into an image though. Dunno if thats possible

You can use box2d and create bodies with the polygon data from the object layer.

It is pretty simple, I managed to do it with this:

public void loadBodies(MapLayer objects, Array<Body> bodies) {
		BodyDef def = new BodyDef();
		PolygonShape shape = new PolygonShape();

		for (MapObject object : objects.getObjects()) {
			if (object instanceof RectangleMapObject) {
				Rectangle rect = ((RectangleMapObject) object).getRectangle();

				def.position.x = (rect.x + rect.width / 2) / 10;
				def.position.y = (rect.y + rect.height / 2) / 10;
				def.type = BodyType.StaticBody;

				shape.setAsBox(rect.width / 2 / 10, rect.height / 2 / 10);

				bodies.add(world.createBody(def));
				bodies.get(bodies.size - 1).createFixture(shape, 0);
			}

			if (object instanceof PolylineMapObject) {
				float vertices[] = ((PolylineMapObject) object).getPolyline()
						.getTransformedVertices();
				for (int x = 0; x < vertices.length; x++) {
					vertices[x] /= 10;
				}
				ChainShape shape2 = new ChainShape();
				shape2.createChain(vertices);
				def.position.set(0, 0);
				cuerpos.add(world.createBody(def));
				cuerpos.get(cuerpos.size - 1).createFixture(shape2, 0);
			}
		}
	}

This code works for rectangle objects and polyline objects. The divitions by 10 are there because for me 1 meter is equivalent to 10 pixels, but you can use any ratio you like.

Hope it helps you.

Cool! This seems like a good way to do it.

And how would you set up the collision detection?
I’m not using box2D and not using bodies atm in my gameworld.

The way I am usually doing collision detection is keep track of player’s x & u coordinates; & use that to set up a rectangle that will be used for collision detection.

I assume I should create a body and give it the dimensions of that same rectangle and then check if a body intersects with another body ??

His polygons are convex if he separates them intelligently.

You’re either going to need to do complicated math (like SAT, as mentioned), or you’ll need a physics library. There really is no other way around it. You could also use the Area class if you want to do things as inefficiently as possible. :stuck_out_tongue:

You could also do pixel-based collision, which is easier to understand for non-mathy people and is fast enough on low resolutions to be good. It’s basically tile collision at a very tiny level. Generally you’d do a bounding box collision first, then do pixel-based collision if a BB collision occurred.

Seems like you don’t know to much about box2d. Do some research on it. It may look a little confusing at first but its quite simple to use specially if you are just needing collision detection.