Y velocity changing on horizontal path, without external forces

Aug 7, 2012 at 12:46 AM

I'm in the process of creating a game where the main structure comes from making a "body" jump over obstacles as it approaches them. I have set it up so that I can determine if the "body" is in the air (jumping) by looking at the Y velocity, and I change the texture of "body" dependent on if it is in the air or not, but there seems to be a problem.

The ground doesn't seem to be smooth because the "body" flickers textures at every instance it hits another "HitGround" tile, which means the Y velocity is changing at every tile. Is there any other way I can determine if my body is off the ground or in a jumping state? Or am I missing something to make the "ground" smooth?

The map I am using is very much like the example provided, utilizing "HitGround", except with different tile sizes (40x40), the "body" is set at 40x34.

Coordinator
Aug 7, 2012 at 8:23 AM

My suggestion would be to keep a boolean flag, let's call it "onGround", that is initialised to true (and correspondingly set the player at rest on the ground).

When the user hits the jump button/key (and as long as onGround == true to prevent turning your jump into a jetpack!), onGround is set to false and an upward velocity (assuming negative for up) is assigned.

As long as the user is in this state (onGround == false), the Y position is updated with the Y velocity and in turn the latter is updated by a downward (positive) acceleration. Thus the velocity should, over a span of frames, vary from upward (negative) to downward (positive) in a typical ballistic trajectory. Note that at the top of the jump, your Y velocity will be 0 (or near 0), hence it is not a good indicator of whether the player is standing on a block or not.

Also, while in the onGround == false state, you then check if the velocity is downward and a solid block is hit, in which case you then set onGround to true, kill the Y velocity and set the Y position to the top of the block. Note that the check for negative velocity is important to allow the player to jump up through a platform but stop when coming down through it. Also, setting the Y position to the top of the block then collision is detected is important to correct penetration into the block since the velocity will typically update the Y position by several pixels into the solid block.

Now, to get back to choosing your sprite frame, you can check the onGround flag to determine whether you are using a walking or jumping sprite. If you also factor the Y velocity, with this check you can further have different sprites for when still going up and when coming back down.

Hope that helps.

Aug 8, 2012 at 3:10 PM
Edited Aug 8, 2012 at 4:23 PM

Great advise, I'm a little confused on how I can go about creating a state though. What I've done is simply allow canJump to be true when contact to a TYPE_GROUND is made and when jumping check to see if that value is true then change it to false right before the jump. I'm getting a little glitch though where sometimes the body is able to do double jumps randomly. In my case where I change the texture when the body is jumping and when it is not, it sometimes doesn't change the texture when the body jumps. The only explanation I can think of is that the body is in contact with the ground right after it jumps for some reason. Am I doing something wrong? Again thanks for your time, it is greatly appreciated.

 

public void BeginContact(Contact contact)
{

    object obj1 = contact.GetFixtureA().GetBody().GetUserData();
    object obj2 = contact.GetFixtureB().GetBody().GetUserData();

    if (obj1 == TYPE_GROUND || obj2 == TYPE_GROUND)
    {
        if (canJump == false) { canJump = true; }
    }
}
public void Jump()
{
    Vector2 p = body.GetPosition();
    if (canJump == true)
    {
        canJump = false;
        body.ApplyForce(new Vector2(0, -1000), p);
    } 
}