Handle wall contact does not work properly on high speed

Hi, the handle_wall_contact function for the skeleton works on max_speed = 50. However, the skeleton falls off the screen when the max_speed is set to 200.

What have I done wrong? Here is my Defold project folder.

Jamie Actual Defold - BABA TRY IT.zip (280.4 KB)

How thick is the collision object for the floor? Without having looked at the project I’m thinking the skeleton just skips it entirely at certain speeds.

I am using tile from a tile set to create the ground and wall so I don’t know how to describe exactly the thickness of it. I think the skeleton is moving so quickly before the collision between the skeleton and wall happen and hence the skeleton went pass the wall and drop off the screen. Any trick how to deal with this type of issue?

1 Like

Yes, that sounds like what I was thinking.

Unfortunately I’m not very experienced with platformers.

Raycasts allow you to, well, cast a ray to detect if it hits an object. That should work but might be overkill. Some reading on raycasts:

I guess you could also paint invisible collision tiles to thicken the floor, but that sounds like a really messy solution to me.

Perhaps someone more experienced with platforming in Defold can help?

Another way to address this might be to enable the “bullet” option of the collision object that’s moving fast. If that doesn’t help, you’re looking at raycasting as @Alex_8BitSkull mentioned.

image

2 Likes

I just looked at this briefly. I didn’t find the issue, but I can say that it is definitely not due to skipping through the wall from one frame to the next. The enemy is not moving nearly fast enough for that. So there is something wrong with the collision-handling code. The physics debug shows correct contact normals for a couple frames, but the skeleton is not being held back out of the wall tiles.


screenshot_2022-10-08_10-51-58

2 Likes

I have the exact same issue.
Bullet solution doesn’t work since the collision object is kinematic.

EDIT: In my case it happens only when using go.animate for position or reallyy high speeds

3 Likes

I found the issue, it has to do with a flag you use: “self-wall_contact”. This flag is unnecessary and leads to your problem:

elseif message.group == group_wall and not self.wall_contact then
	print("!!!!!!!!!!!!!HIT WALL!!!!!!!!!!!!!!!!")
	handle_wall_contact(self, message.normal, message.distance)
end

You then set the flag to true here:

local function handle_wall_contact(self, normal, distance)

	--self.velocity.x = 0

	local proj = vmath.dot(self.correction, normal)
	local comp = (distance-proj) * normal

	self.correction = self.correction + comp

	print (self.correction)
	print (comp)
	print (go.get_position()+comp)
	go.set_position(go.get_position()+comp)

	--[[
	if normal.x ~= 0 then 
		self.wall_contact = true
		self.movement = self.movement*-1
	end
	]]--

	self.wall_contact = true
	self.movement = normal.x

	proj = vmath.dot(self.velocity, normal)
	if proj < 0 then
		self.velocity = self.velocity - proj * normal
	end
end

This means: you only handle the collision when the skeleton has not hit the wall. Once the skeleton has made the first contact with the wall (and you can get multiple contacts every frame), there is no more collision handling and the skeleton goes through the wall.

8 Likes