Help with Platform-based Collision Response

Questions about the LÖVE API, installing LÖVE and other support related questions go here.
Forum rules
Before you make a thread asking for help, read this.
Post Reply
Zorochase
Prole
Posts: 21
Joined: Sun May 21, 2017 10:40 pm
Contact:

Help with Platform-based Collision Response

Post by Zorochase »

I'm using STI to load and draw Tiled maps for my game. I have maps set up such that an object layer contains objects that indicate the position and dimensions of solid "platforms" that the player should be able to walk on. These platforms are made up of tiles that the player can't fall through or walk through. All of the platforms have been stored in a table. My idea was to loop through this table and check to see if the player is colliding with any of the platforms in the table. I was able to do this with BoundingBox.lua. I'm not using bump or any other detection library; detection isn't the problem here - response is. I can't figure out exactly how to make it so the player can't slide through or clip to the platforms. To be more specific, if the player jumps below a platform, their y-velocity should become 0 and they should fall back down to the ground (the ground would also be made up of "platforms" - for now, I made it so the player can't fall through the bottom of the screen, but that's temporary). The player should also be able to stand on top of the platform and push against it.

I found an older demo I wrote a while back - it works, sort of. I found it only worked so well because the player and the singular tile I used to test collisions had the same dimensions. I'm not sure whether it also worked because I wasn't drawing to a canvas and/or I wasn't trying to flip the player's sprite by negating the scale. When I tried to change the width and height of the player in the demo by changing its sprite, the player would clip into the tile and slip over it... you can see it for yourself, I attached it below. Here is the code I used to respond to the collision in the demo:

Code: Select all

-- s1 would be the player
-- s2 would be the test tile
-- yspd is the player's y velocity
function resolveSides(s1, s2)
	if AABB(s1.x,s1.y,s1.w,s1.h, s2.x,s2.y,s2.w,s2.h) then
		-- TOP:
		if (s1.x + s1.w > s2.x or s1.x < s2.x + s2.w) and (s1.y + s1.h > s2.y and s1.y + s1.h < s2.y + s2.h/2) and s1.yspd > 0 then
			s1.yspd = 0
			s1.y = s2.y - s1.h
		-- BOTTOM:
		elseif (s1.x + s1.w > s2.x + 5 and s1.x < s2.x + s2.w - 5) and (s1.y < s2.y + s2.h and s1.y > s2.y + s2.h/2) then
			s1.yspd = 0
			s1.y = s2.y + s1.h
		-- RIGHT:
		elseif (s1.y + s1.h > s2.y or s1.y < s2.y + s2.h) and (s1.x + s1.w > s2.x and s1.x + s1.h < s2.x + s2.w/2) then
			s1.x = s2.x - s1.w
		-- LEFT:
		elseif (s1.y + s1.h > s2.y or s1.y < s2.y + s2.h) and (s1.x < s2.x + s2.w and s1.x > s2.x + s2.w/2) then
			s1.x = s2.x + s1.w
		end
	end
end
TL;DR - How do I make my player object respond to collision with platforms on all sides (how do I keep it from clipping to, sliding over and falling through platforms) without the use of external libraries (like bump) or love.physics?
Attachments
lovecollision.love
Try changing the sprite in player.lua.
(9.91 KiB) Downloaded 128 times
"I am a tomato. My favorite food is tomatoes. Tomatoes are the best. I eat them everyday. I love to hear them scream."
User avatar
Link
Prole
Posts: 19
Joined: Tue Jun 19, 2018 4:09 am

Re: Help with Platform-based Collision Response

Post by Link »

This answer on StackOverflow describes the basic approach: https://stackoverflow.com/a/2657184 (reposting for prosperity)
1. After applying movement, it checks for collisions.
2. It determines the tiles the player overlaps based on the player's bounding box.
3. It iterates through all of those tiles...
3.1 If the tile being checked isn't passable:
3.2 It determines how far on the X and Y axes the player is overlapping the non-passable tile
3.3 Collision is resolved only on the shallow axis:
3.3.1 If Y is the shallow axis (abs(overlap.y) < abs(overlap.x)), position.y += overlap.y; likewise if X is the shallow axis.
3.3.2 The bounding box is updated based on the position change
3.4 Move on to the next tile...
And you'd reduce the velocity depending on whether x/y was the shallow axis - so if you collide with something above, you might set velocity to 0, and if you collide with something to the right/left you only might reduce velocity a little (to achieve a "sliding" effect against the platform).

If you have loads of tiles you need to check for collisions then it might get slow to check all of them in a loop, and at that point you want some method of dividing your world into a "grid" (spatial partitioning) to speed up detection and only check nearby objects, for which there are various algorithms.

Personally I'm using the bump library :)
User avatar
pgimeno
Party member
Posts: 3548
Joined: Sun Oct 18, 2015 2:58 pm

Re: Help with Platform-based Collision Response

Post by pgimeno »

Zorochase wrote: Thu Jun 28, 2018 12:21 am I'm not using bump or any other detection library; detection isn't the problem here - response is.
To be clear, Bump is not just a collision detection library, it's most prominently a collision response library.

Zorochase wrote: Thu Jun 28, 2018 12:21 amTL;DR - How do I make my player object respond to collision with platforms on all sides (how do I keep it from clipping to, sliding over and falling through platforms) without the use of external libraries (like bump) or love.physics?
Apart from what Link has already added, here are some explanations and links by the author of Bump:

viewtopic.php?f=4&t=83908&p=212348#p212348
Post Reply

Who is online

Users browsing this forum: Google [Bot] and 138 guests