9
\$\begingroup\$

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

\$\endgroup\$
5
  • \$\begingroup\$ Relevant (unlikely duplicate): How do I handle moving platforms in a platform game?. \$\endgroup\$ Commented Jul 25, 2011 at 8:31
  • \$\begingroup\$ I read that thread, but since I do not use nodes in any way, it feels like it didn't solve the issue. The game that I am building is tile based, but the moving platforms will be implemented like above (free moving). Using nodes would require a rewrite of my engine as a whole, which I already spent a long long time on. I guess I was hoping someone would look at the code and offer a solution similar to whats proposed, or find an improvement to the code. \$\endgroup\$
    – Kid
    Commented Jul 25, 2011 at 10:44
  • \$\begingroup\$ You would be using nodes once you implement that solution to moving platforms, even if that's the only place you use them. It would solve your sliding problem. \$\endgroup\$ Commented Jul 25, 2011 at 12:22
  • 2
    \$\begingroup\$ " (some games prefer having it like this, but it doesn't feel natural and is not wanted here)" How does it not "feel natural"? Google Inertia and Momentum... \$\endgroup\$
    – Riki
    Commented Jul 26, 2011 at 5:34
  • 1
    \$\begingroup\$ @Felheart, Natural in terms of game play, not real physical world. If you play Super Mario Bros or any of the classic platformers, you'll notice that they do NOT preserve momentum whilst jumping on moving platforms. It disrupts the feel of standing and interacting with a moving platform. \$\endgroup\$
    – Kid
    Commented Jul 26, 2011 at 18:24

1 Answer 1

17
\$\begingroup\$

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.

\$\endgroup\$
5
  • \$\begingroup\$ Excellent! Firstly thanks for the solution to the jumping and penetrating the vertical platform (works!). And second, you are right, the code is terrible in this state. Although this isn't the game in itself, this is a fast prototype made to experiment and understand moving platforms better. Nevertheless, if I am to translate this to the actual games code, I should keep a more structured and object oriented code. It will smoothen the transfer. Now, concerning jSpeias solution, I think I get the node-tree concept, it's just that I don't know how to implement it properly. \$\endgroup\$
    – Kid
    Commented Jul 26, 2011 at 18:18
  • \$\begingroup\$ My first thought is to make Boolean values that would describe the players state, such as: "onFloor", "onPlatform", "onGround", "falling", "jumping", etc. And then run through an if-statement in the enterFrame event that checks the current state and changes Players properties accordingly(?) For example: if(Hero.onPlatform == true){ Player.x = platform.x (relative to players global x);} . Something in that manner. \$\endgroup\$
    – Kid
    Commented Jul 26, 2011 at 18:19
  • \$\begingroup\$ I am working on it as we speak, but at the same time I am separating the code into different classes as you suggested, which is also being slightly confusing (communicating inbetween platform/collision/player classes is mind bending). \$\endgroup\$
    – Kid
    Commented Jul 26, 2011 at 18:20
  • \$\begingroup\$ @Kid: Player has a method GetPosition and internal variables parent (for its parent node) and position (for its position relative to its parent). Player.GetPosition() returns position + parent.GetPosition(). Its parent does the same thing until you reach the root of the tree - the world node. When your player moves, you deal only with the private position variable. Your player is drawn on the game screen according to GetPosition()'s value. I will let you figure out how transition between nodes. ;) \$\endgroup\$ Commented Jul 26, 2011 at 23:29
  • \$\begingroup\$ Having a player class knowing how to modify its own velocity of course is not upholding separation of concerns \$\endgroup\$
    – Andy Ray
    Commented Apr 24, 2017 at 1:43

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .