Trouble with Tile Map Collisions


#1

Hello everyone,

So I have followed tutorials and read through the docs. In doing so I was trying to implement collisions between my Kinematic Player and the Tile Map. I am new to defold so excuse me if the solution ends up being a simple one.

My Player game object has a collisionobject that has a box shape.
My collision handling code for the player looks like this:

local function handle_geometry_contact(self, normal, distance)
	-- project the correction vector onto the contact normal
	-- (the correction vector is the 0-vector for the first contact point)
	local proj = vmath.dot(self.correction, normal)
	-- calculate the compensation we need to make for this contact point
	local comp = (distance - proj) * normal
	-- add it to the correction vector
	self.correction = self.correction + comp
	-- apply the compensation to the player character
	go.set_position(go.get_position() + comp)
	-- check if the normal points enough up to consider the player standing on the ground
	-- (0.7 is roughly equal to 45 degrees deviation from pure vertical direction)
	if normal.y > 0.7 then
		self.ground_contact = true
	end
	-- project the velocity onto the normal
	proj = vmath.dot(self.velocity, normal)
	-- if the projection is negative, it means that some of the velocity points towards the contact point
	if proj < 0 then
		-- remove that component in that case
		self.velocity = self.velocity - proj * normal
	end
end

function on_message(self, message_id, message, sender)
	if message_id == hash("contact_point_response") then
		print("we are colliding!")
		-- check if we received a contact point message. One message for each contact point
		if message.group == hash("default") then
			handle_geometry_contact(self, message.normal, message.distance)
		end
	end
end

I have created a tilesource with my square image for floors. I added a tilemap as well. The tilemap references the tilesource and the tilesource I “painted” or assigned the collision group named “default”.

My masks and groups for collisions are matching for both player and tilesource (where player’s group is “player” and mask is “default” and vice versa for the tilemap).

The collision shape assigned in the tilesource is the same placeholder image. All ‘Z’ values are set to ‘0’ for player and tilemap.

Finally I created the tilemap game object and included both the player and tilemap in the main collection. However my player is not colliding with the tilemap for some reason. I tried selecting the physics debug tool and I do not see a collider on the tilemap at all in game. Also my code in the player script has a console print message if it has any collisions but isn’t printing that there are collisions. When I look back at the tilesource and my collision shape, it makes a colored square border for the tile. I am not sure at this point what could be causing the collision to not register. I briefly changed the tilemap physics to “Dynamic” to see if it would be affected by physics at least and it did fall, but still not sure why collisions aren’t working.

Let me know if there is anything more I can share that might help debug the issue!


#2

You need to add a collision object to the game object with the tilemap component and use the tilemap itself as the shape.


#3

Thanks for the response britzl! Example below where level1 gameobject is what you are talking about:

I am still having trouble getting collisions to work for some reason if I did that part correct.
It’s weird that even as the player passes through the tilemap level game object, that no collisions are being printed to the console (I have a print() in the player’s on_message like below)

function on_message(self, message_id, message, sender)
	if message_id == hash("contact_point_response") then
		print("we are colliding!")
		-- check if we received a contact point message. One message for each contact point
		if message.group == hash("default") then
			handle_geometry_contact(self, message.normal, message.distance)
		end
	end
end

. I tried Debug checkbox for physics but it doesn’t look any different then when I unchecked it, which seems like another red flag that the collision box isn’t even there for some reason. I’m stumped :confused:

What else could I check for that might be giving me these headaches? Thanks again for your patience and help, I’m super excited to get working with Defold, it has been my favorite 2d Engine so far.

Some other screens shots that show a bit more about my project:

Also I made sure my masks / groups where matching (player - group=player, mask=default)(tilemap - group=default, mask=player)


#4

Hey did you set the collision shape to your image at the bottom of the tile source settings.


#5

Good question. I checked and I did in fact add my placeholder square img (same img) as my collision on the bottom of the tile source settings: (at the bottom right)


#6

Please share the project with me and I can take a look (bjorn.ritzl@gmail.com)

EDIT: Even better, check this example and compare with what you have created yourself.

CODE: https://github.com/britzl/publicexamples/tree/master/examples/tilemap_collisions
HTML5: http://britzl.github.io/publicexamples/tilemap_collisions/index.html