Climbing ropes and collision

Hey guys, decided to add a rope climbing feature to my game. So I have a rope item in the game that can be used while the player is in the ledge grab state. My issue is collision while in this state. The player will often times go too low on the rope and end up in a wall or if they try to jump off of it, they'll get stuck in the wall if the rope was too close to the wall or something. Here's the code I have for the ledge grab state:

Code:
if sprite_index = spr_hero || sprite_index = spr_hero_run {
    sprite_index = spr_hero_ledge_grab;
}

if sprite_index = spr_hero_torch_unlit || sprite_index = spr_hero_torch_unlit_run || sprite_index = spr_hero_torch_unlit_swing {
    sprite_index = spr_hero_ledge_grab_torch_unlit;
}

if sprite_index = spr_hero_torch || sprite_index = spr_hero_torch_run || sprite_index = spr_hero_torch_swing {
    sprite_index = spr_hero_ledge_grab_torch;
}

var jkey = keyboard_check(vk_space);
var dkey = keyboard_check(ord('S'));

if (jkey) {
    vspd = -jspd;
    state = scr_move_state;
}

if (dkey) && !place_meeting(x, y, obj_rope_drop) {
    state = scr_move_state;
}

if sprite_index = spr_hero_torch_hurt || sprite_index = spr_hero_hurt || sprite_index = spr_hero_torch_unlit_hurt {
    y -= 1;
    state = scr_move_state;

    // Vertical collisions
    if (place_meeting(x, y+vspd, obj_wall)) {
        while (!place_meeting(x, y+sign(vspd), obj_wall)) {
            y+= sign(vspd);
        }
        vspd = 0;
    }
}

if instance_number(obj_rope_drop) < 3 {
    if (keyboard_check_pressed(vk_up)) && (((inventory.rope1 = true && selector.coorleft = true) || (inventory.rope2 = true && selector.coorcenter = true) || (inventory.rope3 = true && selector.coorright = true))) {
        instance_create(x, y, obj_rope_drop);
    }
}

if (dkey) && place_meeting(x, y, obj_rope_drop) && !place_meeting(x, y-2, obj_wall) {
    y += 1;
}
if keyboard_check(ord('W')) && place_meeting(x, y, obj_rope_drop) && !place_meeting(x, y+1, obj_wall) {
    y -= 1;
}
He goes up and down the rope just fine, well besides sometimes glitching out and the player not being on the rope. The rope drop item is 2 pixels wide and 94 pixels long with origins at 1, 0. The player has a centered origin and is 16 by 16. Messing with the player's origin will likely mess up other parts of the game, whereas messing with the rope will be more helpful. Thanks for the help!

Note: The rope works pretty well most of the time, but it can be game breaking when stuck in a wall. It's also a bit weird because the last bit of code helps the collision while on a rope, but to create a rope, the player must be touching a wall (thus the ledge grab) so once the player creates a rope, they suddenly cannot move. To solve this, the player must jump off the rope and then land back on it (a mere minor issue compared to getting sucked into the walls).
 

jo-thijs

Member
Shouldn't this:
Code:
!place_meeting(x, y-2, obj_wall)
be this?
Code:
!place_meeting(x, y+1, obj_wall)
and this:
Code:
!place_meeting(x, y+1, obj_wall)
be this?
Code:
!place_meeting(x, y-1, obj_wall)
This also looks like an unsafe idea:
Code:
if sprite_index = spr_hero_torch_hurt || sprite_index = spr_hero_hurt || sprite_index = spr_hero_torch_unlit_hurt {
    y -= 1;
As for getting stuck when jumping off a rope, that doesn't seem to be a problem created by this code.
Do your collision masks change with the sprite index?
Because that isn't a good idea either.
 
Last edited:
@jo-thijs no. When I press S, I want the character to go down, so I increase the y by saying y += 1. When I want it to go up, by pressing W, I decrease the y by saying y -= 1. The !place_meeting is saying "if you're not touching a wall, you can move", so that also does not need to be changed. Because otherwise it would be saying that they can only move if they're touching a wall, which is not what I want. I had it set to 1 instead of 2 for the collision with walls below you for a while, but the player kept getting stuck in walls below them so I decreased the y further for the place_meeting so that the player hopefully would not collide with the wall below them and get stuck, but that didn't seem to work very well. I'm not having issues with the directions and collision usually works fine, except I'm having trouble stopping the player from lowering too far on the rope and thus getting stuck in the wall below them.

And nope, collision masks don't change. Thanks for trying to help though :) hopefully we can pinpoint the issue
 

jo-thijs

Member
@jo-thijs no. When I press S, I want the character to go down, so I increase the y by saying y += 1. When I want it to go up, by pressing W, I decrease the y by saying y -= 1. The !place_meeting is saying "if you're not touching a wall, you can move", so that also does not need to be changed. Because otherwise it would be saying that they can only move if they're touching a wall, which is not what I want.
Your code is saying that when pressing S, the player can move down if the player is not touching a wall above him.
This doesn't make sense, it should be if the player is not touching a wall below him.

As for the getting stuck when jumping off, that's very likely a design error that cannot be fixed through code.
I'm guessing the player is wider than the rope is and gets stuck in the wall that way.
However, if masks don't change, then this should keep the player from climbing ropes directly next to walls altogether.
I am missing some information here, so please provide more code and/or object information.
 
@jo-thijs thanks for the help! The part about the place_meeting with the walls is the part you were absolutely correct about. My error was that I was thinking the place_meeting x and y was the wall's x and y, not the player's. That's why I was checking above when the player was going down and vice versa. Thanks for pointing that error out to me! :)
 
@jo-thijs it fixed most of them :) all the game breaking issues at least. Now the only issue seems to be that you can jump and grab onto the rope but it looks like the character is floating in mid air, though this only happens every 1 in 5 times or so
 

jo-thijs

Member
Can you give more details?
Like, how does he float in mid-air?
Does he not change sprites correctly?
Does he not teleport correctly?

What other relevant code do you have?
 
Well when he nears a ledge he enters the ledge grab state, which changes his sprite to look like he's grabbing stuff. Then, if he's in that state and has a rope, he can place it on the map and then climb down or back up it. He can jump off of it and then back on, exiting and re-entering the ledge grab state. But sometimes if you, say, jump from the left onto the rope, then you're on it, and then jump a little more to the right, you'll be floating in mid air but still in the ledge grab state (though jumping takes you out of it and it's not game breaking, just a little weird). I posted pretty much everything in the state. The only other bit of code other than that is the code that tells the state to change if the place_meeting is with the rope (that's in the movement state). Unfortunately I don't have the code with me right now to show you
 

jo-thijs

Member
It sounds like it's an issue with the ledge grab state then.
Can you post the code of the ledge grab state and the code that changes the player to the ledge grab state?
 
Top