Jump to content

P2 Physics: Making Steep Slopes Unclimbable


quarks
 Share

Recommended Posts

I'm still tinkering with a small project to learn more about P2 physics, as mentioned in an earlier post. The issue I'm dealing with now is making uphill movement vaguely realistic. Consider:

 

post-9505-0-15180800-1431391884.png

 

The physics shape for the slope obviously doesn't match the sprite, but that's just for testing. The angle of the slope is more than 80 degrees, and yet the sprite can still climb it. This is pretty close to the limit; any steeper and the sprite can't ascend. Still, 80 degrees.

 

I'm doing typical physics based movement, setting the horizontal velocity to 250 when an arrow key is pressed. gravity.y is 1400. The mass of the sprite is 100, and the platforms are static. I have contact materials set up, but they don't seem to have much effect.

 

Thoughts? 250 px/sec is speedy but not out of bounds for a video game. And at the standard scale for p2, it shouldn't be fast enough to let a sprite climb a nearly vertical slope.

 

Thanks.

Link to comment
Share on other sites

Dang, I have to go to sleep but I'll just quickly mention - this is a common problem in all the physics based platformers I've used. Boot up the Unity platformer demo, put a wall at an angle and you'll notice the same problem.

 

The cause is that the physics engine doesn't understand walls, it's just applying the velocity.x as hard as it can against what it thinks is the floor. That small angle is enough to keep your velocity.x just slightly above 0, so when you hit the wall you just very slowly inch your way up it.

 

When I was using Unity the common fix for this was to raycast a few pixels in front of the player - if a wall is detected the player input in that direction is turned off. Once the player is back on the ground and not facing the wall, the input in that direction is turned back on. I need to sleep but tomorrow I'll try and dig up some old blog posts on this if I have time.

 

Some extra stuff before I go to sleep:

  • If you want to see a funny side effect of physics engines not understanding the difference between floors and walls, check out Counterstrike wall surfing: https://www.youtube.com/watch?v=2_NQradnzFY :)
  • Look into Phasers Ninja physics - it's designed to handle angled floors.
Link to comment
Share on other sites

for vertical walls i did the same thing..  i used a slightly altered version of the "checkifcanjump" function to figure out if the player is touchingLeft or touchingRight and if so i canceld the movement..   BUT.. this function would probably also prohibit climbing 45deg hills..  

Link to comment
Share on other sites

Hi,

You can adjust the applied velocity depending on the contact normal with the ground. If the contact normal is straight up, add all velocity, and if not just add less. Sounds good?

You should be able to use the dot product between the up vector and the contact normal to scale your applied velocity.

Have a look at the checkIfCanJump() function in the p2 character demo, it extracts the contact normal between ground and the character body: https://schteppe.github.io/p2.js/examples/canvas/character.html

Link to comment
Share on other sites

Thanks for the replies. I had wondered if it was going to necessary to handle slopes "manually" with contact normals or somesuch; apparently it is.

 

But isn't this something that the physics system should handle automatically? Real objects traveling 12.5 m/s can't run up straight up walls. I get that the problem arises from setting the velocity directly. Is there a more realistic way to implement movement, say by applying a constant force instead?

Link to comment
Share on other sites

Here are the links I was thinking of that discusses this issue. They talk a lot about raycasting (and the first link is about Unity), but the math and concepts are all the same: 

http://deranged-hermit.blogspot.ca/2014/02/2d-physics-in-unity-with-raycasts-slopes.html

http://www.gamasutra.com/blogs/YoannPignole/20131010/202080/The_hobbyist_coder_1_2D_platformer_controller.php?print=1
 
One thing I messed up in my original post (serves me right making sleep deprived posts!) was when I mentioned "if a wall is detected the player input in that direction is turned off", that's actually a solution for when you hit solid 90' walls (as valueerror pointed out). Some physics engines have an issue where if you hit a wall and your velocity.x is > 0, the player just ends up sticking to the wall. In your case what you want to do (which the article discusses) is to basically fire out a ray from the player, get the angle of the slope and then multiply the players velocity by that.
 
Since raycasting isn't as easy in Phaser as Unity, you could build yourself a set of 3-4 sloped floors and then hardcode the angles into them. Then when the player collides with it you have a factor you can multiply the velocity by. There's still some edge cases to take care of but I think that's probably the easiest way.

Link to comment
Share on other sites

 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...