Character stuck in wall

I'm new to GameMaker 2 and I'm having trouble with collision/walls. I'm able to make my character walk around, but when I touch side walls, I can only move away from the wall, not up or down. I don't have the same issue with the bottom and top walls.

Here is my code:

GML:
walk_speed = 3;

if (keyboard_check(vk_up))
{
    sprite_index = walk_back;
    // If there is not a wall walk_speed away
    if (!place_meeting(x, y - walk_speed, oWall))
    {
        // Move walk_speed
        y -= walk_speed;
    }
    // Otherwise, there is a wall walk_speed away
    else
    {
        // So move 1 pixel up until you are next to the wall
        while (!place_meeting(x, y - walk_speed, oWall))
        {
            y--;
        }
    }
}

if (keyboard_check(vk_left))
{
    sprite_index = walk_left;
    // If there is not a wall walk_speed away
    if (!place_meeting(x - walk_speed, y, oWall))
    {
        // Move walk_speed
        x -= walk_speed;
    }
    // Otherwise, there is a wall walk_speed away
    else
    {
        // So move 1 pixel up until you are next to the wall
        while (!place_meeting(x - walk_speed, y, oWall))
        {
            x--;
        }
    }
}

if (keyboard_check(vk_right))
{
    sprite_index = walk_right;
    // If there is not a wall walk_speed away
    if (!place_meeting(x + walk_speed, y, oWall))
    {
        // Move walk_speed
        x += walk_speed;
    }
    // Otherwise, there is a wall walk_speed away
    else
    {
        // So move 1 pixel up until you are next to the wall
        while (!place_meeting(x + walk_speed, y, oWall))
        {
            x++;
        }
    }
}

if (keyboard_check(vk_down))
{
    sprite_index = walk_front;
    // If there is not a wall walk_speed away
    if (!place_meeting(x, y + walk_speed, oWall))
    {
        // Move walk_speed
        y += walk_speed;
    }
    // Otherwise, there is a wall walk_speed away
    else
    {
        // So move 1 pixel up until you are next to the wall
        while (!place_meeting(x, y + walk_speed, oWall))
        {
            y++;
        }
    }
}


if(keyboard_check_released(vk_down)){
   sprite_index = front_idle;
}

if(keyboard_check_released(vk_up)){
   sprite_index = back_idle;
}

if(keyboard_check_released(vk_left)){
   sprite_index = left_idle;
}

if(keyboard_check_released(vk_right)){
   sprite_index = right_idle;
}
If my character is against a vertical object (that I'm using for a wall) like this, then she can only walk away from the wall (to the right, not up or down).

1620001261696.png

However, if my character is against a horizontal object, then she can walk left/right, and up:
1620001328001.png

Unsure of why it's doing this. Any help is appreciated. Thanks!
 

Mk.2

Member
First thing that stands out:

GML:
   if (!place_meeting(x, y - walk_speed, oWall))
    {
        // Move walk_speed
        y -= walk_speed;
    }
    // Otherwise, there is a wall walk_speed away
    else
    {
        // So move 1 pixel up until you are next to the wall
        while (!place_meeting(x, y - walk_speed, oWall))
        {
            y--;
        }
    }
This is saying "if there isn't a collision at y - walk _speed, then do this. Else, if there is a collision at y - walk_speed, then while there isn't a collision at y - walk_speed, do this". The condition for the while loop to run clearly can never be true. I'm guessing that what you meant is this:

GML:
        while (!place_meeting(x, y - 1, oWall))
As for the issue you're having, make sure the mask dimensions are consistent for all the character's sprites, or simply use a seperate sprite and set it as the object's mask using the mask_index function.
 
Last edited:

Kreastricon

Member
There is nothing wrong with your code, I just ran it in a game I made today and it works fine.

I did make an improvement to the code.

In every while statement, I changed "walk speed" to the number "1" so that the player directly touches the wall. This way you can use any walk speed you want and there will never be a gap between the player and the wall.

Whatever is making you code get stuck in the left and right walls, it is being caused by something else.

Check your collision masks and make sure your player is lined up to a grid if possible.

GML:
walk_speed = 3;

if (keyboard_check(vk_up))
{
    sprite_index = walk_back;
    // If there is not a wall walk_speed away
    if (!place_meeting(x, y - walk_speed, oWall))
    {
        // Move walk_speed
        y -= walk_speed;
    }
    // Otherwise, there is a wall walk_speed away
    else
    {
        // So move 1 pixel up until you are next to the wall
        while (!place_meeting(x, y - 1, oWall))
        {
            y--;
        }
    }
}

if (keyboard_check(vk_left))
{
    sprite_index = walk_left;
    // If there is not a wall walk_speed away
    if (!place_meeting(x - walk_speed, y, oWall))
    {
        // Move walk_speed
        x -= walk_speed;
    }
    // Otherwise, there is a wall walk_speed away
    else
    {
        // So move 1 pixel up until you are next to the wall
        while (!place_meeting(x - 1, y, oWall))
        {
            x--;
        }
    }
}

if (keyboard_check(vk_right))
{
    sprite_index = walk_right;
    // If there is not a wall walk_speed away
    if (!place_meeting(x + walk_speed, y, oWall))
    {
        // Move walk_speed
        x += walk_speed;
    }
    // Otherwise, there is a wall walk_speed away
    else
    {
        // So move 1 pixel up until you are next to the wall
        while (!place_meeting(x + 1, y, oWall))
        {
            x++;
        }
    }
}

if (keyboard_check(vk_down))
{
    sprite_index = walk_front;
    // If there is not a wall walk_speed away
    if (!place_meeting(x, y + walk_speed, oWall))
    {
        // Move walk_speed
        y += walk_speed;
    }
    // Otherwise, there is a wall walk_speed away
    else
    {
        // So move 1 pixel up until you are next to the wall
        while (!place_meeting(x, y + 1, oWall))
        {
            y++;
        }
    }
}


if(keyboard_check_released(vk_down)){
   sprite_index = front_idle;
}

if(keyboard_check_released(vk_up)){
   sprite_index = back_idle;
}

if(keyboard_check_released(vk_left)){
   sprite_index = left_idle;
}

if(keyboard_check_released(vk_right)){
   sprite_index = right_idle;
}
 

TheouAegis

Member
Make sure the distance from the origin to each of the bounding box sides in the sprites are identical. If your wal_left and walk_right sprites have narrower bounding boxes than the other sprites,then when you change to walk_back, it changes the bounding boxso that now the player is actually inside the wall, so you can't move up or down.
 

Kreastricon

Member
Another thing you can do to prevent this from happening again is that you can add code to push the player outside of the wall if it ever teleports or is placed inside of one.
GML:
//Run at the end of movement code.

var d=0; //Direction to check
var i=1; //Pixel length

//If stuck in a wall after moving

while place_meeting(x,y,oWall)
    {
    //Check direction
    var xx=lengthdir_x(i,d);
    var yy=lengthdir_y(i,d);

    //If there is no wall in that direction
    if !place_meeting(x+xx,y+yy,oWall)
        {
        x=x+xx
        y=y+yy
        }else{
        //Check the next orthogonal direction.
        d+=90
           if d=0//If all directions were checked and none were empty
            {
            i+=1 //Move up an extra pixel.
            }
        }

    }
 
Last edited:
Make sure the distance from the origin to each of the bounding box sides in the sprites are identical. If your wal_left and walk_right sprites have narrower bounding boxes than the other sprites,then when you change to walk_back, it changes the bounding boxso that now the player is actually inside the wall, so you can't move up or down.
This was the issue. Thank you so much!!! šŸ˜„
 
Top