GMS 2 Problems with jump height in a 2D platformer

Clawson

Member
Hi all, looking for some help with a problem I'm having getting pixel-perfect jump heights in a 2D platformer.
I started with the usual that most tutorials (Shaun Spalding, Heartbeast) suggest, ie
Code:
//in create
hsp = 0
vsp = 0
grv = 0.3
jumpheight = -7
...other variables, etc.

//in step event
...keys definition, movement, collision checking, gravity, etc...then

if (place_meeting(x,y+1,oWall)) && (key_jump)
    {
         vsp = jumpheight;
    }
where 'jumpheight' is a negative number has already been set in the create event and key_jump is a 'keyboard_check_pressed' function. Eventually after much trial and error I managed to graduate to
Code:
    if (grounded == true) && (key_jump) && !(key_duck)
    {
        vsp = jumpheight;
    }
where 'grounded' is set based on 'if placemeeting(x, y+1...etc). Both of these worked to an extent, however the problem I'm having is that when I run my game, the actual jump height is inconsistent - I have an asset layer in my test room with a line indicating where the top pixel of the character's head should reach when they jump (I was using this to test what I needed the jumpspeed and gravity variables to be to achieve the height I wanted), and maybe half of the time this is reached, the other half of the time my character stops anywhere between 1-4 pixels short before gravity kicks in and reverses the movement. After some measurement of my sprites I know that I want the peak of my jump height to be 38 pixels up from my characters current position.

As I understand it, isn't lengthdir_y(n,dir) supposed to return the speed required to move n pixels in the direction specified? so I set jumpheight = 38 (since I want to jump exactly 38 pixels and rearranged my code and tried
Code:
    if (grounded == true) && (key_jump) && !(key_duck)
    {
        vsp = lengthdir_y(jumpheight,90);
    }
since GM2 considers 90 degrees as 'up', but this just sends my character to space at rocket speed, and while I can get something closer to what I want by manipulating my gravity variable, the jump arc is running at the speed of light. No dice. So I tried
Code:
    if (grounded == true) && (key_jump) && !(key_duck)
    {
        y = y + lengthdir_y(jumpheight,90);
    }
Which achieves the desired pixel perfect jump height but of course simply teleports the player to that location (and may as well just be y = y+jumpheight anyway).

I've managed to clamp my acceleration up to a maximum walk speed when moving and lerp my hspeed to a stop when the player releases the movement keys, so from that I'm suspecting that I'll have to use clamp to limit the rate of accelleration and lerp to slow down to the peak of the jump before gravity accelerates their fall, but I'm at a complete loss as to how to implement this.

Does anyone have any suggestions or can point me in the direction of any tutorials? is lengthdir_y even a useful function in this case? am I barking up the wrong tree entirely? Many thanks in advance for any help!
 
Last edited:

Catastrophe

Member
tl;dr vsp = power(2*grv*jumpHeight,0.5)

Well lengthdir_x/y is generally only useful if you want to either program at a non-right angle, or programmatically measure distance to an angle. There's no difference between

y = y + lengthdir_y(jumpheight,90)
and
y = y - jumpHeight

It's not useful in this case to answer your question. Brushing off highschool physics (or googling haha) is the best answer here. You want to determine the initial velocity V needed reach a height of Y with a gravity G (which will be whatever it is in your game, not 9.8)

According to this:
https://math.stackexchange.com/questions/785375/calculate-initial-velocity-to-reach-height-y/785397
It's v = sqrt(2gY)

or in your case probably something like:
vsp = power(2*grv*jumpHeight,0.5)

Now, if you're throwing something at an angle (probably not jumping, in a platformer, which is usually a straight making a vsp a given value to start with) that's where lengthdir_y can be handy, to determine the vertical velocity component if vsp is unknown and you only known speed and direction

Edit: vsp might need to be negative that equation, I'm too lazy to check your code. One of those should work, though.

Edit: Okay I think I see your issue further. Getting literal pixel perfect jump height actually might be tricky, because this isn't the real world where we're simulated at infinite FPS.

I think the only way to do this, if you want actual 100% accuracy, is to simply cap it at the top when it reaches your ideal jumpheight. E.g. when you're doing your y += vsp in code, and you have a jumpheight set, subtract vsp from that jumpheight, and if the jumpheight reaches negative, add that amount and stop further y changes until vsp changes so you're going down again. And simply overestimate your initial vsp a tad

Alternatively, just keep guessing at the correct vsp if you just need a very specific one.
 
Last edited:
Top