I'm working of a 2d platformer. It's a preety simple game, but the ground is flat and it looks boring. I did the collision detection for it and it's all working when the boxes are axis aligned, but I want to add slopes so it's more interesting. I researched a lot and I found the separating axis theorem but I read that it is not good for platformers because it's not side specific. So, my question is: what is the best way to detect collision with curves and slopes? I use javascript if you want to provide some code. Thanks in advance!
1 Answer
For horizontal boxes AABB is great, for slopes, you need to add a twist to it.
The height of a slope that's positioned between x1 and x2 at a specific point can be calculated the following way (x is the point we want to get the height at, h1 is the height at x1 and h2 is the hight at x2):
height := (x - x1) / (x2 - x1) * (h2 - h1) + h1
Now, first you need to check if the player collides with the aabb of the slope (this is the broad phase), if it does, then get the height of it at the player's position.
Next, check if the player's height is less than the result, if it is and he's fallong, then set his y coordinate to the height of the slope and if he has one, set his vertical velocity to 0.
This doesn't work with the underside of the slopes, if you want that too, you need to do the same for that too.
-
\$\begingroup\$ Made an edit to the above equation. Since the algorithm doesn't follow traditional PEMDAS, I added parentheses around division operation as this is required to happen first before multiplication operation. So it should look like this: height := ((x - x1) / (x2 - x1)) * (h2 - h1) + h1 \$\endgroup\$ Jan 27, 2017 at 3:43
-
\$\begingroup\$ @Savior Uhm, no. Divisions and multiplications are cummilatibve, it doesn'f matter in which order I do them. Get your maths right. \$\endgroup\$– BálintJan 27, 2017 at 6:31
-
\$\begingroup\$ No need to get touchy dude, but your statement isn't fully correct. I also think you mean "commutative" instead of "cumulative", but that's only true for multiplication, not division. If you leave out the parenthesis, some compilers will help apply them for you, but not all are guaranteed to. Additionally, putting the parenthesis on the division or the multiplication produce different results.: (noParen = 5.5; divParen = 5.5; mulParen = 4.041). Although some programming languages might be able to run PEMDAS on an equation, not all will. It's better to call out what you want done. \$\endgroup\$ Jan 27, 2017 at 19:16
-
\$\begingroup\$ @SaviorXTanren What I wanted to say was that it doesn't matter in which order you apply the stuff here.
(x - x1) / (x2 - x1) * (h2 - h1)
always equals(x - x1) / ((x2 - x1) * (h2 - h1))
and((x - x1) / (x2 - x1)) * (h2 - h1)
. I was a bit tired at the time I wrote that comment, so I didn't express myself good enough \$\endgroup\$– BálintJan 27, 2017 at 19:34 -
\$\begingroup\$ Understandable, but as I just showed above, that's not the case. So you can't put the parenthesis in either spot and get the same result. If you type out your first equation directly into some C# code, it gives you the "right" answer. Even if you move the multiplication part to in front of the division, it still gives you the right answer. But that's also a computer doing the right thing. In the event that someone sees this and decides to breakup the equation into multiple parts, you want to make sure they are aware that depending on how they do it, they can get a wrong answer. \$\endgroup\$ Jan 27, 2017 at 19:37