Search code examples
actionscript-3flashanimationhittest

AS3 landing smoothly under affect of Gravity


I'm attempting a to make a fighting game with multiple platforms. I've successfully made the controls, movement, (double)jumping, and gravity parts of the game.

The issue is, when a player jumps, upon reaching the ground, they seem to go a bit deeper than they should on the platform (they should land and stay on the surface of the platform). This is more visible when the player double jumps.

I know why this happens; it's because sometimes hitTestObject takes a while to react when objects come in too quickly.

So, the first thing I thought of is to make the player's foot's y axis equal to the y axis of the top of the platform he lands on.

Though, that solution resulted in a rather jerky landing.

My question is: Is there a way to make the player to land smoothly on the top surface of the platform?

Some things I've tried:

-Raising FPS, it just made the same effect happen, but more quickly.

-Decreasing the speed at which the player falls, but that makes the game less fun, so I've crossed it out.

And here's my relevant code:

stage.addEventListener(Event.ENTER_FRAME, loop);
var jumpConstant:Number = 30;
var gravityConstant:Number = 1.8;
function loop(e:Event):void //happens 
{
    if(player.leg1.foreleg1.foot1.hitTestObject(platforms.ground)||player.leg2.foreleg2.foot2.hitTestObject(platforms.ground)) //if either of the player's legs are colliding with the platform [ps: nested movieclips]
    {
        player.ySpeed = 0; //the player stops going downwards
        player.y = platforms.y; //the player's y becomes the platform's y. don't worry, it puts the player in the right place, just not smoothly.
        if (player.b_up) //if Up control button (W or Up Arrow) is being pressed
        {
            player.ySpeed = -player.jumpConstant; //make the player jump

        }
    else //if the player isn't colliding with the platform
    {
        player.ySpeed += player.gravityConstant; //the player is affected by gravity and is pulled downwards
    }

Link to the game if you wanna try it out to see the jerky effect:

http://www.fastswf.com/-64Ux3I


Solution

  • The problem is that you are only checking for a collision at increments of ySpeed. Since y speed increases during a fall by 1.8 per step, you are quickly looking at collision checks spaced widely apart. If you want pixel precise collision checks, you need to check for collision at 1px increments. This means if y speed is 10, you need 10 collision checks during one loop update. Use a for loop within your loop function to accomplish this.