SOLVED Need help with current ladder code - all assistance appreciated

jcg3729

Member
I'm trying to do some basic ladder code without state (since I'm not very good writing them) and below is what I have (scroll to the end of second code posted).
While the current ladder code works my problem is the player 1) keeps bouncing on top of the ladder once they reach the top----bouncing even continues when I jump off the ladder onto the ground after touching said ladder AND 2) once the player hits the bottom after touching ladder they go right below the ground and fall through the ground platform.
I've played with it a little bit looking at other examples but I can't figure out what I'm doing wrong, which I'm sure it's an easy fix.
All help is appreciated if any.

Problem 1:
p1.PNG
Problem 2:
p2.PNG

Ladder object code:
Nothing

**Ladder object is layered above another object called "ladder mask" which has no code either.

Player object code:

Create

GML:
/// @description Player variables



grav = 0.6;

hsp = 0;

vsp = 0;

jumpspeed = 10;

movespeed = 5;

slidemax = 15;

slide = slidemax;

sliding = false;

Step
GML:
/// @description Insert description here

// You can write your code in this editor

//Get the player's input

var key_right = keyboard_check(vk_right);

var key_left = keyboard_check(vk_left);

var key_jump = keyboard_check_pressed(vk_space);

var key_run = keyboard_check(vk_shift);

var key_duck = keyboard_check(vk_down);

key_plat = keyboard_check(vk_space);



var onground = place_meeting(x, y + 1, o_solid);



//React to inputs

hsp = (key_right - key_left) * movespeed;

if vsp < 10

    vsp += grav;



if onground and !key_duck

    vsp = key_jump * -jumpspeed;



if (slide >= 0 and key_duck and key_jump and onground)

or (sliding) {

    slide--;

    slideanim = true;

    hsp = image_xscale * 25;

    sliding = true;



    alarm[1] = 45;



    if slide < 0 or !onground {

        hsp = 0;

        sliding = false;

        slide = -1;

    }

}



//run speed

if onground

    if key_run and (key_left or key_right)

        movespeed = 10;

    else

        movespeed = 5;



//Horizontal Collision

if place_meeting(x + hsp, y, o_solid) {

    while !place_meeting(x + sign(hsp), y, o_solid)

        x += sign(hsp);

    hsp = 0;

}

x += hsp;



//Vertical Collision

if place_meeting(x, y + vsp, o_solid) {

    while !place_meeting(x, y + sign(vsp), o_solid)

        y += sign(vsp);

    vsp = 0;

}

y += vsp;





//Wall Jumps

if (place_meeting(x+1,y,o_solid)) && (!place_meeting(x-1,y,o_solid))

{

    if (key_jump) && (!place_meeting(x,y+1,o_solid))

    {

        vsp -= 12.4;

        hsp -= 5;

    }

}



if (place_meeting(x-1,y,o_solid)) && (!place_meeting(x+1,y,o_solid))

{

    if (key_jump) && (!place_meeting(x,y+1,o_solid))

    {

        grav = normal_grav;;

        vsp -= 12.4;

        hsp += 5;

    }

}

//Wall Slides Left

    if (key_left = -1) && (vsp > 0) && (place_meeting(x-1,y,o_solid)) && (!place_meeting(x,y+1,o_solid))

    {

        if (vsp <= 11) && (vsp > 1.5) vsp -= 1;

        if (vsp <= 11)  && (vsp > 0) grav = .05;



    }

    if (key_left = -1 && (place_meeting(x-1,y,o_solid)) && (!place_meeting(x,y+1,o_solid)))

    {

        grav = normal_grav;

    }

    if (key_left = 0)

    {

        grav = normal_grav;

    }

//Wall Slides Right

    if (key_right = 1) && (vsp > 0) && (place_meeting(x+1,y,o_solid)) && (!place_meeting(x,y+1,o_solid))

    {

        if (vsp <= 16) && (vsp > 1.5) vsp -= 1;

        if (vsp < 10)  && (vsp > 0) grav = .05;



    }

    if (key_right = 1 && (place_meeting(x+1,y,o_solid)) && (!place_meeting(x,y+1,o_solid)))

    {

        grav = normal_grav;

    }

    if (key_right = 0)

    {

        grav = normal_grav;

    }





// Climbing

if place_meeting(x,y,o_ladder) then //if on a ladder...

    {

    grav=0 //Don't fall

    vsp=0

    }

if (keyboard_check(vk_up))then{if place_meeting(x,y,o_ladder){vspeed=-4}}

if keyboard_check_released(vk_up) then{if place_meeting(x,y,o_ladder){vspeed=0}}

//Ladder Down

if (keyboard_check(vk_down)) then{if place_meeting(x,y,o_ladder){vspeed=4}}

if keyboard_check_released(vk_down) then{if place_meeting(x,y,o_ladder){vspeed=0}}
Ladder code inside Step
GML:
// Climbing

if place_meeting(x,y,o_ladder) then //if on a ladder...

    {

    grav=0 //Don't fall

    vsp=0

    }

 if (keyboard_check(vk_up))then{if place_meeting(x,y,o_ladder){vspeed=-4}}

if keyboard_check_released(vk_up) then{if place_meeting(x,y,o_ladder){vspeed=0}}

//Ladder Down

if (keyboard_check(vk_down)) then{if place_meeting(x,y,o_ladder){vspeed=4}}

if keyboard_check_released(vk_down) then{if place_meeting(x,y,o_ladder){vspeed=0}}
 
Last edited:

LEGOlars

Member
You're using both "vspeed" and "vsp". Where vsp is your custom variable, and vspeed is a builtin Gamemaker variable that moves your character.

You only modify your "vspeed" in when place_meeting(x,y,o_ladder) returns true.
So if your character exits collision with the ladder with vspeed -4, it will keep moving up. Then "grav" makes your "vsp" build up to something large enough to counter the -4 vspeed, you start falling down again (-4 + 8 = 4 for example). Then when you hit o_ladder again, the vsp gets set to 0, but not vspeed. So you start going up again.
When you exit the ladder collision with vspeed = 4, you will move through the ground because your normal movement code only cares about "vsp" (not vspeed).

I think the first step to a solution is changing vspeed to vsp.
 
Last edited:

jo-thijs

Member
I'm trying to do some basic ladder code without state (since I'm not very good writing them) and below is what I have (scroll to the end of second code posted).
While the current ladder code works my problem is the player 1) keeps bouncing on top of the ladder once they reach the top----bouncing even continues when I jump off the ladder onto the ground after touching said ladder AND 2) once the player hits the bottom after touching ladder they go right below the ground and fall through the ground platform.
I've played with it a little bit looking at other examples but I can't figure out what I'm doing wrong, which I'm sure it's an easy fix.
All help is appreciated if any.

Problem 1:
View attachment 29619
Problem 2:
View attachment 29620

Ladder object code:
Nothing

**Ladder object is layered above another object called "ladder mask" which has no code either.

Player object code:

Create

GML:
/// @description Player variables



grav = 0.6;

hsp = 0;

vsp = 0;

jumpspeed = 10;

movespeed = 5;

slidemax = 15;

slide = slidemax;

sliding = false;

Step
GML:
/// @description Insert description here

// You can write your code in this editor

//Get the player's input

var key_right = keyboard_check(vk_right);

var key_left = keyboard_check(vk_left);

var key_jump = keyboard_check_pressed(vk_space);

var key_run = keyboard_check(vk_shift);

var key_duck = keyboard_check(vk_down);

key_plat = keyboard_check(vk_space);



var onground = place_meeting(x, y + 1, o_solid);



//React to inputs

hsp = (key_right - key_left) * movespeed;

if vsp < 10

    vsp += grav;



if onground and !key_duck

    vsp = key_jump * -jumpspeed;



if (slide >= 0 and key_duck and key_jump and onground)

or (sliding) {

    slide--;

    slideanim = true;

    hsp = image_xscale * 25;

    sliding = true;



    alarm[1] = 45;



    if slide < 0 or !onground {

        hsp = 0;

        sliding = false;

        slide = -1;

    }

}



//run speed

if onground

    if key_run and (key_left or key_right)

        movespeed = 10;

    else

        movespeed = 5;



//Horizontal Collision

if place_meeting(x + hsp, y, o_solid) {

    while !place_meeting(x + sign(hsp), y, o_solid)

        x += sign(hsp);

    hsp = 0;

}

x += hsp;



//Vertical Collision

if place_meeting(x, y + vsp, o_solid) {

    while !place_meeting(x, y + sign(vsp), o_solid)

        y += sign(vsp);

    vsp = 0;

}

y += vsp;





//Wall Jumps

if (place_meeting(x+1,y,o_solid)) && (!place_meeting(x-1,y,o_solid))

{

    if (key_jump) && (!place_meeting(x,y+1,o_solid))

    {

        vsp -= 12.4;

        hsp -= 5;

    }

}



if (place_meeting(x-1,y,o_solid)) && (!place_meeting(x+1,y,o_solid))

{

    if (key_jump) && (!place_meeting(x,y+1,o_solid))

    {

        grav = normal_grav;;

        vsp -= 12.4;

        hsp += 5;

    }

}

//Wall Slides Left

    if (key_left = -1) && (vsp > 0) && (place_meeting(x-1,y,o_solid)) && (!place_meeting(x,y+1,o_solid))

    {

        if (vsp <= 11) && (vsp > 1.5) vsp -= 1;

        if (vsp <= 11)  && (vsp > 0) grav = .05;



    }

    if (key_left = -1 && (place_meeting(x-1,y,o_solid)) && (!place_meeting(x,y+1,o_solid)))

    {

        grav = normal_grav;

    }

    if (key_left = 0)

    {

        grav = normal_grav;

    }

//Wall Slides Right

    if (key_right = 1) && (vsp > 0) && (place_meeting(x+1,y,o_solid)) && (!place_meeting(x,y+1,o_solid))

    {

        if (vsp <= 16) && (vsp > 1.5) vsp -= 1;

        if (vsp < 10)  && (vsp > 0) grav = .05;



    }

    if (key_right = 1 && (place_meeting(x+1,y,o_solid)) && (!place_meeting(x,y+1,o_solid)))

    {

        grav = normal_grav;

    }

    if (key_right = 0)

    {

        grav = normal_grav;

    }





// Climbing

if place_meeting(x,y,o_ladder) then //if on a ladder...

    {

    grav=0 //Don't fall

    vsp=0

    }

if (keyboard_check(vk_up))then{if place_meeting(x,y,o_ladder){vspeed=-4}}

if keyboard_check_released(vk_up) then{if place_meeting(x,y,o_ladder){vspeed=0}}

//Ladder Down

if (keyboard_check(vk_down)) then{if place_meeting(x,y,o_ladder){vspeed=4}}

if keyboard_check_released(vk_down) then{if place_meeting(x,y,o_ladder){vspeed=0}}
Ladder code inside Step
GML:
// Climbing

if place_meeting(x,y,o_ladder) then //if on a ladder...

    {

    grav=0 //Don't fall

    vsp=0

    }

if (keyboard_check(vk_up))then{if place_meeting(x,y,o_ladder){vspeed=-4}}

if keyboard_check_released(vk_up) then{if place_meeting(x,y,o_ladder){vspeed=0}}

//Ladder Down

if (keyboard_check(vk_down)) then{if place_meeting(x,y,o_ladder){vspeed=4}}

if keyboard_check_released(vk_down) then{if place_meeting(x,y,o_ladder){vspeed=0}}
The bug is due to you using 2 different movement system mixed together:
one for normal movement where you use your own variables and collision system
and one for climbing ladders, where you use vspeed without resetting them to 0 afterwards.

The solution is to use a single movement system, like so:
GML:
/// @description Insert description here
// You can write your code in this editor
// Get the player's input
var key_right = keyboard_check(vk_right);
var key_left = keyboard_check(vk_left);
var key_up = keyboard_check(vk_up);
var key_down = keyboard_check(vk_down);
var key_jump = keyboard_check_pressed(vk_space);
var key_run = keyboard_check(vk_shift);
var key_duck = keyboard_check(vk_down);
key_plat = keyboard_check(vk_space);

var onground = place_meeting(x, y + 1, o_solid);

// React to inputs
hsp = (key_right - key_left) * movespeed;
if vsp < 10
    vsp += grav;

if onground and !key_duck
    vsp = key_jump * -jumpspeed;

if (slide >= 0 and key_duck and key_jump and onground)
or (sliding) {
    slide--;
    slideanim = true;
    hsp = image_xscale * 25;
    sliding = true;

    alarm[1] = 45;

    if slide < 0 or !onground {
        hsp = 0;
        sliding = false;
        slide = -1;
    }
}

// run speed
if onground
    if key_run and (key_left or key_right)
        movespeed = 10;
    else
        movespeed = 5;

// Climbing
if place_meeting(x,y,o_ladder) { //if on a ladder...
    vsp = (key_down - key_up) * 4;
}

// Horizontal Collision
if place_meeting(x + hsp, y, o_solid) {
    while !place_meeting(x + sign(hsp), y, o_solid)
        x += sign(hsp);
    hsp = 0;
}
x += hsp;

// Vertical Collision
if place_meeting(x, y + vsp, o_solid) {
    while !place_meeting(x, y + sign(vsp), o_solid)
        y += sign(vsp);
    vsp = 0;
}
y += vsp;

// Wall Jumps
if (place_meeting(x+1,y,o_solid)) && (!place_meeting(x-1,y,o_solid))
{
    if (key_jump) && (!place_meeting(x,y+1,o_solid))
    {
        vsp -= 12.4;
        hsp -= 5;
    }
}

if (place_meeting(x-1,y,o_solid)) && (!place_meeting(x+1,y,o_solid))
{
    if (key_jump) && (!place_meeting(x,y+1,o_solid))
    {
        grav = normal_grav;;
        vsp -= 12.4;
        hsp += 5;
    }
}

// Wall Slides Left
    if (key_left = -1) && (vsp > 0) && (place_meeting(x-1,y,o_solid)) && (!place_meeting(x,y+1,o_solid))
    {
        if (vsp <= 11) && (vsp > 1.5) vsp -= 1;
        if (vsp <= 11)  && (vsp > 0) grav = .05;

    }
    if (key_left = -1 && (place_meeting(x-1,y,o_solid)) && (!place_meeting(x,y+1,o_solid)))
    {
        grav = normal_grav;
    }
    if (key_left = 0)
    {
        grav = normal_grav;
    }
// Wall Slides Right
    if (key_right = 1) && (vsp > 0) && (place_meeting(x+1,y,o_solid)) && (!place_meeting(x,y+1,o_solid))
    {
        if (vsp <= 16) && (vsp > 1.5) vsp -= 1;
        if (vsp < 10)  && (vsp > 0) grav = .05;

    }
    if (key_right = 1 && (place_meeting(x+1,y,o_solid)) && (!place_meeting(x,y+1,o_solid)))
    {
        grav = normal_grav;
    }
    if (key_right = 0)
    {
        grav = normal_grav;
    }
 

jcg3729

Member
You're using both "vspeed" and "vsp". Where vsp is your custom variable, and vspeed is a builtin Gamemaker variable that moves your character.

You only modify your "vspeed" in when place_meeting(x,y,o_ladder) returns true.
So if your character exits collision with the ladder with vspeed -4, it will keep moving up. Then "grav" makes your "vsp" build up to something large enough to counter the -4 vspeed, you start falling down again (-4 + 8 = 4 for example). Then when you hit o_ladder again, the vsp gets set to 0, but not vspeed. So you start going up again.
When you exit the ladder collision with vspeed = 4, you will move through the ground because your normal movement code only cares about "vsp" (not vspeed).

I think the first step to a solution is changing vspeed to vsp.
You are absolutely right! I super forgot to change the syntax when I was fumbling around with the code. After doing the change it works just as intended fixing both problems! Thank you!
 

jcg3729

Member
The bug is due to you using 2 different movement system mixed together:
one for normal movement where you use your own variables and collision system
and one for climbing ladders, where you use vspeed without resetting them to 0 afterwards.

The solution is to use a single movement system, like so:
GML:
/// @description Insert description here
// You can write your code in this editor
// Get the player's input
var key_right = keyboard_check(vk_right);
var key_left = keyboard_check(vk_left);
var key_up = keyboard_check(vk_up);
var key_down = keyboard_check(vk_down);
var key_jump = keyboard_check_pressed(vk_space);
var key_run = keyboard_check(vk_shift);
var key_duck = keyboard_check(vk_down);
key_plat = keyboard_check(vk_space);

var onground = place_meeting(x, y + 1, o_solid);

// React to inputs
hsp = (key_right - key_left) * movespeed;
if vsp < 10
    vsp += grav;

if onground and !key_duck
    vsp = key_jump * -jumpspeed;

if (slide >= 0 and key_duck and key_jump and onground)
or (sliding) {
    slide--;
    slideanim = true;
    hsp = image_xscale * 25;
    sliding = true;

    alarm[1] = 45;

    if slide < 0 or !onground {
        hsp = 0;
        sliding = false;
        slide = -1;
    }
}

// run speed
if onground
    if key_run and (key_left or key_right)
        movespeed = 10;
    else
        movespeed = 5;

// Climbing
if place_meeting(x,y,o_ladder) { //if on a ladder...
    vsp = (key_down - key_up) * 4;
}

// Horizontal Collision
if place_meeting(x + hsp, y, o_solid) {
    while !place_meeting(x + sign(hsp), y, o_solid)
        x += sign(hsp);
    hsp = 0;
}
x += hsp;

// Vertical Collision
if place_meeting(x, y + vsp, o_solid) {
    while !place_meeting(x, y + sign(vsp), o_solid)
        y += sign(vsp);
    vsp = 0;
}
y += vsp;

// Wall Jumps
if (place_meeting(x+1,y,o_solid)) && (!place_meeting(x-1,y,o_solid))
{
    if (key_jump) && (!place_meeting(x,y+1,o_solid))
    {
        vsp -= 12.4;
        hsp -= 5;
    }
}

if (place_meeting(x-1,y,o_solid)) && (!place_meeting(x+1,y,o_solid))
{
    if (key_jump) && (!place_meeting(x,y+1,o_solid))
    {
        grav = normal_grav;;
        vsp -= 12.4;
        hsp += 5;
    }
}

// Wall Slides Left
    if (key_left = -1) && (vsp > 0) && (place_meeting(x-1,y,o_solid)) && (!place_meeting(x,y+1,o_solid))
    {
        if (vsp <= 11) && (vsp > 1.5) vsp -= 1;
        if (vsp <= 11)  && (vsp > 0) grav = .05;

    }
    if (key_left = -1 && (place_meeting(x-1,y,o_solid)) && (!place_meeting(x,y+1,o_solid)))
    {
        grav = normal_grav;
    }
    if (key_left = 0)
    {
        grav = normal_grav;
    }
// Wall Slides Right
    if (key_right = 1) && (vsp > 0) && (place_meeting(x+1,y,o_solid)) && (!place_meeting(x,y+1,o_solid))
    {
        if (vsp <= 16) && (vsp > 1.5) vsp -= 1;
        if (vsp < 10)  && (vsp > 0) grav = .05;

    }
    if (key_right = 1 && (place_meeting(x+1,y,o_solid)) && (!place_meeting(x,y+1,o_solid)))
    {
        grav = normal_grav;
    }
    if (key_right = 0)
    {
        grav = normal_grav;
    }
Thank you as well, jo-thijs for fleshing out that bit of the code! I did notice after changing the syntax out from vspeed to vsp movement was a bit gimmicky moving about the room.

Before I close the thread:
While it doesn't have to do with the focus on the thread now the ladder code is solved the next part I would like to do is ledge grabs--do you have any particular hints or words of wisdom?
 

Sabnock

Member
you really should try and get your head around States as they are super useful and certain elements of games would be really hard to achieve without them and tbh once you get it you will ask yourself why you thought it was so hard to understand.

There a re numerous tutorials on you tube on how to set them up using switch{} case :

here is a link to the first one that comes up in a google search and is probably the one that most GMS beginner peeps learn from

 
Last edited:

jcg3729

Member
I'm familiar with both tutorials but after awash of abandoned projects just working on player mechanisms trying to use states I sort of gave up on using this. While I'm aware it chops down the code and makes things more fluid between player actions I understand the tidbits spaghetti code abit more.... --not saying your information wasn't helpful (as I am a super noob at gml).
 
Top