XNA Creators Club Online
Page 1 of 1 (9 items)
Sort Posts: Previous Next

Heightmap and jumping Question

Last post 7/9/2007 6:08 AM by Chryso. 8 replies.
  • 7/5/2007 5:41 PM

    Heightmap and jumping Question

    I have gone through reimer's tutorials and have some nice terrain generated by a heightmap.  I also have an algorithm to figure out the height given X and Y coordinates of an object.  I am now trying to add in a jump feature and have gotten close but it still is not working properly.

    When I jump, my object jumps up at a reasonable rate but as soon as it reaches its apex, the object seems to fall too fast.  Also moving while jumping seems to mess it up as well.

    Anyone see where I made a mistake?

            float jumpTime;
    float objectHeight;
    void CalculateJumpVelocity(GameTime gameTime, bool requestJump)
    {
    float jumpStrength = 1f;

    float terrainHeight = GetTerrainHeight(cameraPosition.X, cameraPosition.Y);

    if (requestJump)
    {
    jumpTime = 0;
    objectHeight = terrainHeight;
    }

    jumpTime += (float)gameTime.ElapsedGameTime.TotalSeconds;

    float newHeight = objectHeight + jumpStrength * jumpTime + .5f * -9.81f * jumpTime * jumpTime;

    if (newHeight > terrainHeight)
    {
    cameraPosition.Z += newHeight - terrainHeight;
    objectHeight = newHeight;
    }
    else
    camState = cameraState.terrainFollow;
    }

  • 7/5/2007 9:20 PM In reply to

    Re: Heightmap and jumping Question

    Perhaps you should set up a constant value for the TerminalVelocity of any jumpable object. The Terminal Velocity is the max velocity at which something falls. For games you should have it in units per second so its easy to work with. For the object have a velocity that you use to calculate its current speed and then have a gravity constant, example.


    public const TerminalVelocity = 60;
    public const Gravity = 20;

    the object should have a location, and a velocity. when the user hits 'JUMP' the velocity is set so the location changes and the gravity takes hold. if the velocity is not equal to 0 then you should check the current height of the object. if the objects height <= the height at the current terrain spot then velocity should be set to 0 and the objects height should be reset accordingly. Each frame you should also check that if velocity != 0 then if the user tries to move the object it doesnt change x direction it just slows or quickens the x velocity. Example:

    Im assuming your doing a 2D game you didnt specify. if you are doing a 3D then please let me know so I can fix it.

    sorry if im unclear at all its late, and that was alot of freehand typing

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    public const TerminalVelocity = 60;
    public const Gravity = 20;

    public class JumpObject
    {
    //Current Location
    private Vector2 _Location = Vector.Zero;
    private Vector2 _Velocity = Vector.Zero;

    //Occurs when user wants object to jump.
    public void Jump(float Speed) {
    //Check if the hes already jumping, if not apply jump
    if (_Velocity.Y == 0)
    _Velocity.Y = Speed;
    }

    //Occurs when they want to move right
    public void MoveRight(float Speed) {
    _Velocity.X = Speed;
    if (_Velocity.Y == 0)
    //Flip Sprite here if Sprite is not already pointing right (you can check this by checking if _Velocity.X is positive)
    }

    //Occurs when the want to move left
    public void MoveLeft(float Speed) {
    _Velocity.X = Speed;
    if (_Velocity.Y == 0)
    //Flip Sprite here if Sprite is not already pointing right (you can check this by checking if _Velocity.X is negative)
    }

    //Update every frame
    public void Update(GameTime gameTime) {
    //Time in seconds since last update
    float Deltatime = gameTime.ElapsedGameTime.TotalSeconds;
    //Actual Speed of the falling object
    Vector2 Speed = new Vector2(_Velocity.X, _Velocity.Y + Gravity);
    //Check if its falling faster than its terminal velocity
    if (Speed.Y > TerminalVelocity)
    Speed.Y = TerminalVelocity;
    //Increase location by velocity and gravity
    _Location += Speed * Deltatime;
    //Check to see if the object is jumping
    if (_Velocity.Y != 0) {
    //Get the Height of land where the object is above
    float CurrentHeight = GetHeight(_Location.X, _Location.Y);
    //If the object is below the terrain set it to the correct level and set velocity to zero
    if
    (_Location.Y <= CurrentHeight) {
    _Velocity = Vector2.Zero;
    _Location.Y = CurrentHeight;
    }
    }
    }
    }


  • 7/5/2007 9:57 PM In reply to

    Re: Heightmap and jumping Question

    Thanks for the reply Phil!

    I just skimmed through what you wrote and saw you asking if I was doing this in 2d or 3d.  I am doing this in 3d.

    Tommorrow I will look over what you said in more detail because I have to be getting to bed now (or I will never get up for work :D)
  • 7/6/2007 11:53 PM In reply to

    Re: Heightmap and jumping Question

    Ok well what type of 3D game are you making? does the unit move in all directions? If so what variable do you use to decide the rotation of the guy. Give me a detailed description of the gameplay if you dont mind so I can match your needs more specifically
  • 7/7/2007 10:46 PM In reply to

    Re: Heightmap and jumping Question

    Well I am making an action adventure game (like zelda:ocarina of time).  The player himself can rotate on the y axis (turning left and right).  He can move around in the x and z directions, he can strafe left and right too.  He can move up and down by jumping or walking up stairs and such.  The heightmap takes care of his height when he is on the terrain. 

    So yea, it is just like most other action adventure games, movement wise.  If you need more info just let me know.

    Thanks again for helping me :D
  • 7/8/2007 10:01 AM In reply to

    Re: Heightmap and jumping Question

    ok a couple more questions before I do some stuff..

    what are the variable names that your using for the players location and rotation
    are you using the Vector3 structure for 3D points in your game
    what are the functions in your characters class (just the name so I know the method of you moving him around)
  • 7/8/2007 12:27 PM In reply to

    Re: Heightmap and jumping Question

    Vector3 position holds the character's position
    Vector3 moveVector holds the vector which will be added to characterPosition
    float rotation holds the rotation data for rotating left and right (around the Y axis)

    I don't have much in my character class yet.
    MoveForward()
    MoveBackward()
    RotateLeft()
    RotateRight()
    StrafeLeft()
    StrafeRight()
    Also have the character's world matrix that I just use in the draw call.
    Matrix worldMatrix.
  • 7/8/2007 11:03 PM In reply to

    Re: Heightmap and jumping Question

    Ok heres what I came up with, I set it all up in the 'Link' class just so you could see the added variables and functions I added, here it is...
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    public class Link
    {
    //Constants
    //=Change these to mod Link's jump
    //=If you increase Gravity and JumpSpeed proportionately then
    // he will jump faster but still achieve the same height.
    //=If you decrease the gravity he will jump higher but could
    // get unwated air time so increase gravity by some and
    // Jumpspeed by alot more.
    public const float Gravity = 100;
    public const float TerminalVelocity = -250;
    public const float JumpSpeed = 200;
    //Variables
    public Vector3 Position = Vector3.Zero;
    public Vector3 MoveVector = Vector3.Zero;
    public float UpwardVelocity = 0f;
    public float Rotation = 0f;
    public Matrix WorldMatrix = Matrix.Identity;
    //Functions
    public void MoveForward() { } //Code here
    public void MoveBackward() { } //Code here
    public void RotateLeft() { } //Code here
    public void RotateRight() { } //Code here
    public void StrafeLeft() { } //Code here
    public void StrafeRight() { } //Code here
    //Jump method
    public void Jump() {
    //Makes sure Link isn't already in the air
    if (!InAir) {
    UpwardVelocity = JumpSpeed;
    InAir = true;
    }
    }
    //Calls on every frame with '(float)gameTime.ElapsedGameTime.TotalSeconds' as Deltatime
    public void Update(float Deltatime) {
    if (InAir) {
    //Since Link is jumping increase his vertical position by Upwardvelocity
    Position.Y += UpwardVelocity * Deltatime;
    //Apply Gravity to UpwardVelocity so Link falls back down
    UpwardVelocity -= Gravity * Deltatime;
    //Restrain Link from falling faster then TerminalVelocity
    if (UpwardVelocity < TerminalVelocity)
    UpwardVelocity = TerminalVelocity;
    //Get the CurrentHeight of the Land below Link
    float CurrentHeight = GetHeight(Position.X, Position.Y);
    //Check if Link is below or equal to the landheight,
    //if so then stop him from jumping and reset him to the terrain
    if (Position.Y <= CurrentHeight) {
    UpwardVelocity = 0f;
    Position.Y = CurrentHeight;
    }
    }
    }
    //Used to determine if hes jumping
    public bool InAir
    {
    get { return (UpwardVelocity != 0); }
    }
    }

  • 7/9/2007 6:08 AM In reply to

    Re: Heightmap and jumping Question

    Hello,
    Depending on the effect you want you might not which to use the following:
                Position.Y += UpwardVelocity * Deltatime;
    //Apply Gravity to UpwardVelocity so Link falls back down
    UpwardVelocity -= Gravity * Deltatime;

    Because when you multiply the upward velocity by the delta time you forget the factor for acceleration which is 0.5 as shown in your first post.
    Lets push your model a bit:

    You have Position.Y += UpwardVeolicty * Deltatime;
    So, deltaYPosition = UpwardVeolicty * DeltaTime; (just some renaming here)

    UpwardVelocity = (oldSpeed - Gravity * DeltaTime );

    which gives
    deltaYPosition = ( oldSpeed - Gravity * DeltaTime) * DeltatTime; (even if it is only on the next cycle that this applies)

    so deltaYPosition = oldSpeed * DeltatTime - Gravity * DeltaTime * DeltaTime;

    Here you are squaring DeltaTime which has for consequences to nearly ignore gravity since milliseconds * milliseconds gives out microseconds.

    It is easier to use a jumpTime as you had in your first example.

    (general DeltaPosition equation would be: DeltaPosition =  InitialSpeed * DeltaTime + 0.5 * g * DeltaTime* (old Time + newTime)
    where g is -9.81

    Hope it helps you realize a correct jump function

    Regards,
    Chryso






    <!-- I am not perfect, therefor I am -->
Page 1 of 1 (9 items) Previous Next