Friday, May 13, 2016

actionscript 3 - How to handle physics of moving platforms in a platformer?


So after a few hours of searching on the internet, I have yet to find a pleasing answer on how to handle moving platforms in a 2d platform game. So I decided to make a simple prototype where you interact with 2 different platforms, one that moves vertically and one horizontally. I would love some help to dissect and see what isn't working, and how to fix them. I have submitted the .fla file + .as file below, accompanied with a link to the playable .swf.


The goal is to make the Hero interact with the platforms as if they were solid objects that he can stand on, pushed alongside with, jump on/under etc etc.


The problems with my prototype are these:





  • When you stand on the horizontally moving platform, without moving (not touching any keys), the Hero moves along with platform, but with a slight delay causing hero to slide back a little.




  • When you stand on the horizontally moving platform, and jump, you move along with the platform midair (some games prefer having it like this, but it doesn't feel natural and is not wanted here). Which might be caused by the Hero retaining the velocity on the X-axis from the platform.




  • When you jump up to the bottom side on the vertically moving platform, whilst the platform is moving downwards, you sink inside it for a brief second. Hero penetrates through as if the collision was non existent for a moment.




  • When you jump on vertically moving platform, the veloctiy on Y-axis is retained, so when you walk off the platform, you fall down at a higher speed. With the speed of the retained velocity, + gravity that is added (this is mostly because I cant figure out a way to reset velocity on Y-axis to 0 when you land on the platform, without the player freezing midair).





I'm a novice programmer so I am sure there are BETTER ways to do this, and I would love to hear them all. Any ideas on how to improve the code or other methods in which you can implement moving platforms into a Tilebased game are welcome. In the end, I am trying to find a solid way to handle moving platforms in 2d platformers.


Playable SWF: http://dl.dropbox.com/u/28271061/PlatformerhowtoFLA.html (Move with arrow keys, Jump with X key, Run with Z key)


Sourcecode AS-file: http://dl.dropbox.com/u/28271061/Platformerhowto.as


SourcefileFLA: http://dl.dropbox.com/u/28271061/PlatformerhowtoFLA.fla


If you prefer just to read the code through Pastie online: http://pastie.org/2266764



Answer



Let's separate your problem into its distinct issues...


A word on code quality



Your code currently has your platforms directly controlling your player's velocity and even the world's gravity constant. It's hacky, and it's procedural when it should be object-oriented. Once you start expanding this game things are going to get ugly fast.


You need to refactor your code. Implement a player class, a platform class and a floor class. Separate their concerns: have the player interpret keyboard controls and control how he runs and jumps, and have the platforms alter his momentum as necessary (by adding their own speed to the player's already-determined speed, when necessary).


Have your player determine where it is in regards to a floor-type object (platforms and floors would both have a BodyType = BodyTypes.Floor, or something) and determine on its own where it is in regards to the object, how it should react and whether it's falling or on the ground.


This may deserve a separate topic as it's quite a separate issue from everything you've brought up. However, you're going to have to do it at some point.


Horizontal/vertical inertia when leaving a platform


To solve your vertical and horizontal velocity problems, note two things:



  • Regarding horizontal speed: Your code only sets the horizontal speed to 0 when the player hits the ground (on Pastie line 200) or a platform.

  • Regarding vertical speed: Your player has a constant falling acceleration. When he walks off the vertical platform, this falling acceleration just keeps getting added to his already downward movement.



Your player is simply suffering from inertia: his momentum is maintained until something stops it.


Solution: Both issues would be resolved by jSepia's solution to How do I handle moving platforms in a platform game? as it would completely separate the player's movement process from how the platforms move him. You simply would not fall faster walking off a vertical platform and would not preserve your horizontal momentum jumping off a horizontal one, because the platforms will no longer affect your player's vx and vy.


Note: You may have some difficulty implementing jSepia's solution before your code is refactored.


Slipping side-to-side around the horizontal platform


Your player isn't actually moved horizontally quite as fast as the platform moves. It's not obvious to me why. This problem would also probably be solved by implementing jSepia's solution and properly refactoring your code (the latter would simply make the cause obvious).


Collision detection: overlapping with the vertical platform


See Pastie line 381: every step it's resetting the player's vy to 0 as long as the player's colliding with the underside of the vertical platform. In the following step, vy is increased by the gravity acceleration and then the player's moved (and then it's reset to 0 again).


This means for as long as your player's colliding with the bottom of the platform, he's moving down at a constant speed (the gravity constant). The vertical platform is faster than that so it overlaps him. If the vertical platform moved over a longer distance it would slide right through him until the player was registered as standing on the platform.


Solution: Don't reset the player's vy to 0. Just set the player's vy to the platform's vertical speed (if the platform is travelling downwards). Your player will then be moving away from the vertical platform at least as fast as the platform, and accelerate away from it.


No comments:

Post a Comment

Simple past, Present perfect Past perfect

Can you tell me which form of the following sentences is the correct one please? Imagine two friends discussing the gym... I was in a good s...