A better platform jump

Bentley

Member
I know "better" is vague, sorry. I want a jump that is more "game-like" (that's extremely vague too).
For the longest time I've been terrible at jump codes. Is there anything in the code below I can improve on? Is there another way I can go about it?

Edit: I know the rising/falling variables are pointless. The thought behind using them was that I may want two different speeds, a rise_speed and a fall_speed. But yeah, just letting the vspd go from negative to positive makes the most sense.

CREATE
Code:
state = "normal";
rising = false;
falling = false;
vspd = 8;
grav = 0.2;
STEP
Code:
//Press jump

if (state == "normal") && (keyboard_check_pressed(vk_space))
{
    state = "jump";
    rising = true;
}

//Jump state

if (state == "jump")
{
    //Rise
 
    if (rising)
    {
        if (!place_meeting(x, y - vspd, oWall)) //If there's not a wall above you, rise
        {
            y -= vspd;
            vspd -= grav;
    
            if (vspd < 0) //If you aren't moving up anymore, fall
            {
                rising = false;
                falling = true;
            }
        }
        else //Collide with ceiling, then fall
        {
            while (!place_meeting(x, y - 1, oWall)) y -= 1;
            rising = false;
            falling = true;     
        }
    }
 
    //Fall
 
    if (falling)
    {
        if (!place_meeting(x, y + vspd, oWall))
        {
            y += vspd;
            vspd += grav; //Fall faster
        }
        else
        {
            while (!place_meeting(x, y + 1, oWall)) y += 1;
            falling = false;
            vspd = 8; //Default vspd
            state = "normal";
        }
    }
}
Thanks for reading. Any help is appreciated!
 
Last edited:

CloseRange

Member
you can combine the falling and rising into one by using the sign command, here is how i always deal with jumping using your variables:

CREATE
Code:
c_vspd = 0; // current vspd
vspd = 8;
grav = .2;
STEP
Code:
// Jump if on ground
if (place_meeting(x, y+1, obj_wall)) { // On the ground
     if (keyboard_check_pressed(vk_space)) { // jump key
          c_vspd = -vspd;
     }
} else {
     vspd += grav; // Gravity
}


// Fall/Rise
if (place_meeting(x, y+c_vspd, obj_wall)) {
     while(!place_meeting(x, sign(c_vspd), obj_wall) {
          y += sign(c_vspd); // just like your code but with sign
     }
     c_vspd = 0; // no more falling
}
y += c_vspd;
Hope this helped! :p
-CloseRange


Edit: I noticed a couple of glitches so if you tried the code before i made them sorry they should be fixed now
 

Binsk

Member
EDIT: Ah, beaten to the punch.

Well mathematically I don't really see anything wrong with it. You have done things a bit more complicated than you need to, however.

For example, the whole "rising / falling" separation is unnecessary. What is the difference between 5 - 5 and 5 + (-5)? Nothing. Instead of checking for rising / falling just let vspd keep decreasing into the negatives and keep subtracting it from y. This will make your character automatically start falling without needing a separate if statement.

Your whole jump state could be reduced to something like this:
Code:
if (state == "jump")
{
    if (!place_meeting(x, y - vspd, oWall))
    {
       y -= vspd;
       vspd -= grav;
    }
    else
     {
        while (!place_meeting(x, y - sign(vspd), oWall)) y -= sign(vspd);

        if (vspd < 0) // If we were falling down then we hit ground
        {
           vspd = 8; //Default vspd
           state = "normal";
        }
    }
}
 

Bentley

Member
you can combine the falling and rising into one by using the sign command, here is how i always deal with jumping using your variables:

CREATE
Code:
c_vspd = 0; // current vspd
vspd = 8;
grav = .2;
STEP
Code:
// Jump if on ground
if (place_meeting(x, y+1, obj_wall)) { // On the ground
     if (keyboard_check_pressed(vk_space) { // jump key
          c_vspd = -vspd;
     }
} else {
     vspd += grav; // Gravity
}


// Fall/Rise
if (place_meeting(x, y+c_vspd, obj_wall)) {
     while(!place_meeting(x, sign(c_vspd), obj_wall) {
          y += sign(c_vspd); // just like your code but with sign
     }
     c_vspd = 0; // no more falling
}
y += c_vspd;
Hope this helped! :p
-CloseRange
Thanks for the reply CloseRange. Your way is concise and therefore better : ) Appreciate it.
 

Bentley

Member
Well mathematically I don't really see anything wrong with it. You have done things a bit more complicated than you need to, however.

For example, the whole "rising / falling" separation is unnecessary. What is the difference between 5 - 5 and 5 + (-5)? Nothing. Instead of checking for rising / falling just let vspd keep decreasing into the negatives and keep subtracting it from y. This will make your character automatically start falling without needing a separate if statement.

Your whole jump state could be reduced to something like this:
Code:
if (state == "jump")
{
    if (!place_meeting(x, y - vspd, oWall))
    {
       y -= vspd;
       vspd -= grav;
    }
    else
     {
        while (!place_meeting(x, y - sign(vspd), oWall)) y -= sign(vspd);

        if (vspd < 0) // If we were falling down then we hit ground
        {
           vspd = 8; //Default vspd
           state = "normal";
        }
    }
}
Hey Binsk, you and CloseRange are right. I'll fix that in the original post. Thanks.
 

samspade

Member
I know "better" is vague, sorry. I want a jump that is more "game-like" (that's extremely vague too).
For the longest time I've been terrible at jump codes. Is there anything in the code below I can improve on? Is there another way I can go about it?

CREATE
Code:
state = "normal";
rising = false;
falling = false;
vspd = 8;
grav = 0.2;
STEP
Code:
//Press jump

if (state == "normal") && (keyboard_check_pressed(vk_space))
{
    state = "jump";
    rising = true;
}

//Jump state

if (state == "jump")
{
    //Rise
 
    if (rising)
    {
        if (!place_meeting(x, y - vspd, oWall)) //If there's not a wall above you, rise
        {
            y -= vspd;
            vspd -= grav;
   
            if (vspd < 0) //If you aren't moving up anymore, fall
            {
                rising = false;
                falling = true;
            }
        }
        else //Collide with ceiling, then fall
        {
            while (!place_meeting(x, y - 1, oWall)) y -= 1;
            rising = false;
            falling = true;    
        }
    }
 
    //Fall
 
    if (falling)
    {
        if (!place_meeting(x, y + vspd, oWall))
        {
            y += vspd;
            vspd += grav; //Fall faster
        }
        else
        {
            while (!place_meeting(x, y + 1, oWall)) y += 1;
            falling = false;
            vspd = 8; //Default vspd
            state = "normal";
        }
    }
}
Thanks for reading. Any help is appreciated!

Here's my basic movement code for an object with acceleration. The vertical movement portion of the code (excluding the collision check) is only two lines:

Code:
//set vertical movement code
vsp += grav;

//jumps
if (jump) && (place_meeting(x, y + 1, parent_solid)) {vsp = jump_speed;}

full code

Code:
///create event

//movement variables
hsp        = 0;             //horizontal movement speed
accel      = 0.5
fric       = 0.2
max_hsp    = 6;
carry_hsp  = 0;             //used to track sub-pixel movement
vsp        = 0;             //vertical movement speed
carry_vsp  = 0;             //used to track sub-pixel movement
jump_speed = -12;           //note that jump_speed is negative
grav       = 0.5;             //gravity

///step event

//inputs
var left  = keyboard_check(ord("A")) ||                 //left has two imputs that work
            keyboard_check(vk_left);

var right = keyboard_check(ord("D")) ||                 //right has two imputs that work
            keyboard_check(vk_right);

var jump  = keyboard_check_pressed(vk_space);


//set horizontal movement code
if (left) || (right) {
    hsp += accel * (right - left);
    if (abs(hsp) > max_hsp) {
        hsp = max_hsp * sign(hsp);
    }
} else {
    if (hsp > 0.2) || (hsp < -0.2) {
        hsp -= fric * sign(hsp);
    } else {
        hsp = 0;
    }
}

//set vertical movement code
vsp += grav;

//jumps
if (jump) && (place_meeting(x, y + 1, parent_solid)) {vsp = jump_speed;}

//movement and collision
carry_hsp += hsp;
carry_vsp += vsp;
var hsp_new = round(carry_hsp);
var vsp_new = round(carry_vsp);
carry_hsp -= hsp_new;
carry_vsp -= vsp_new;

repeat(abs(hsp_new)) {
    if (!place_meeting(x + sign(hsp), y, parent_solid)) {
        x += sign(hsp);
    } else {
        hsp = 0;
        break;
    }
}

repeat(abs(vsp_new)) {
    if (!place_meeting(x, y + sign(vsp), parent_solid)) {
        y += sign(vsp);
    } else {
        vsp = 0;
        break;
    }
}
 

Bentley

Member
Here's my basic movement code for an object with acceleration. The vertical movement portion of the code (excluding the collision check) is only two lines:

Code:
//set vertical movement code
vsp += grav;

//jumps
if (jump) && (place_meeting(x, y + 1, parent_solid)) {vsp = jump_speed;}

full code

Code:
///create event

//movement variables
hsp        = 0;             //horizontal movement speed
accel      = 0.5
fric       = 0.2
max_hsp    = 6;
carry_hsp  = 0;             //used to track sub-pixel movement
vsp        = 0;             //vertical movement speed
carry_vsp  = 0;             //used to track sub-pixel movement
jump_speed = -12;           //note that jump_speed is negative
grav       = 0.5;             //gravity

///step event

//inputs
var left  = keyboard_check(ord("A")) ||                 //left has two imputs that work
            keyboard_check(vk_left);

var right = keyboard_check(ord("D")) ||                 //right has two imputs that work
            keyboard_check(vk_right);

var jump  = keyboard_check_pressed(vk_space);


//set horizontal movement code
if (left) || (right) {
    hsp += accel * (right - left);
    if (abs(hsp) > max_hsp) {
        hsp = max_hsp * sign(hsp);
    }
} else {
    if (hsp > 0.2) || (hsp < -0.2) {
        hsp -= fric * sign(hsp);
    } else {
        hsp = 0;
    }
}

//set vertical movement code
vsp += grav;

//jumps
if (jump) && (place_meeting(x, y + 1, parent_solid)) {vsp = jump_speed;}

//movement and collision
carry_hsp += hsp;
carry_vsp += vsp;
var hsp_new = round(carry_hsp);
var vsp_new = round(carry_vsp);
carry_hsp -= hsp_new;
carry_vsp -= vsp_new;

repeat(abs(hsp_new)) {
    if (!place_meeting(x + sign(hsp), y, parent_solid)) {
        x += sign(hsp);
    } else {
        hsp = 0;
        break;
    }
}

repeat(abs(vsp_new)) {
    if (!place_meeting(x, y + sign(vsp), parent_solid)) {
        y += sign(vsp);
    } else {
        vsp = 0;
        break;
    }
}
Hey samspade, I appreciate the reply. Thanks for sharing : )
 
Top