Windows Player Clipping to Wall

D

DarthTenebris

Guest
Hello everybody,

I am currently working on a 2D platformer, and have run into an issue. The player seems to be getting stuck in walls when walking left, but not when walking right, and I don't have a clue why. Perhaps a fresh set of eyes can help me.
Create Event:
GML:
keyLeft = ord("A");
keyRight = ord("D");
keyJump = ord("W");

dir = -1; // 1 = left ; 0 = stop ; -1 = right

spr_spsl = spr_player_static_left;
spr_spsr = spr_player_static_right;
spr_spdl = spr_player_dynamic_left;
spr_spdr = spr_player_dynamic_right;

hspd = 0;
vspd = 0;

minHspd = -0.3;
maxHspd = 0.3;
minVspd = -20;
maxVspd = 20;

grav = 0.05;
wspd = 0.3;
jmp = 3;

onGround = false;
Step Event:
GML:
#region Pre-Step Physics
vspd += grav;

hspd = clamp(hspd, minHspd, maxHspd);
vspd = clamp(vspd, minVspd, maxVspd);

x += hspd;
y += vspd;

if (place_meeting(x, y + 1, obj_block)) {
    onGround = true;
    y -= vspd;
    vspd = 0;
} else {
    onGround = false;
}
#endregion
#region Input Collection
var _left = keyboard_check(keyLeft);
var _right = keyboard_check(keyRight);
var _jump = keyboard_check_pressed(keyJump);
#endregion
#region Input Processing
if ((_left && _right) || (!_left && !_right)) {
    if (dir == 1) {
        if (sprite_index != spr_spsl) {
            sprite_index = spr_spsl;
        }
    } else if (dir == -1) {
        if (sprite_index != spr_spsr) {
            sprite_index = spr_spsr;
        }
    }
    
    dir = 0;
    hspd = 0;
} else if (_left && !_right) {
    dir = 1;
    
    if (sprite_index != spr_spdl) {
        sprite_index = spr_spdl;
    }
    
    if (!place_meeting(x - hspd, y, obj_block)) {
        hspd -= wspd;
    } else {
        x += hspd;
        hspd = 0;
    }
} else if (!_left && _right) {
    dir = -1;
    
    if (sprite_index != spr_spdr) {
        sprite_index = spr_spdr;
    }
    
    if (!place_meeting(x + hspd, y, obj_block)) {
        hspd += wspd;
    } else {
        x -= hspd;
        hspd = 0;
    }
}

if (_jump) {
    if (onGround) {
        vspd -= jmp;
    }
}
#endregion
Any help will be appreciated.

Thank you for your time.
 

Amon

Member
What have you set the pivot to in the sprite editor. Bottom left, Top left etc? I always set mine to bottom centre to avoid issues like this.
 

Nidoking

Member
When the character is moving left, you do this:
Code:
if (!place_meeting(x - hspd, y, obj_block)) {
        hspd -= wspd;
    } else {
        x += hspd;
        hspd = 0;
    }
But hspd is negative, correct? Shouldn't these signs match the case for moving right, except for hspd -= wspd?
 
D

DarthTenebris

Guest
What have you set the pivot to in the sprite editor. Bottom left, Top left etc? I always set mine to bottom centre to avoid issues like this.
That might be the case, I'll check later. By default it's middle center, but I played with sprite resizing and it probably messed the origin.
When the character is moving left, you do this:
Code:
if (!place_meeting(x - hspd, y, obj_block)) {
        hspd -= wspd;
    } else {
        x += hspd;
        hspd = 0;
    }
But hspd is negative, correct? Shouldn't these signs match the case for moving right, except for hspd -= wspd?
The idea is to push the player out if he ever gets stuck in a wall. It works fine walking right, but for some reason doesn't work when walking left.

Thank you for your time.
 

Nidoking

Member
It works fine walking right, but for some reason doesn't work when walking left.
Not just some reason - the reason that you're treating hspd like a positive value when it is a negative value. I was wrong before - all three of the signs need to be switched. That is the problem with moving left that doesn't happen when you're moving right, because when you're moving right hspd is positive, so treating it like a positive value works.
 
D

DarthTenebris

Guest
Not just some reason - the reason that you're treating hspd like a positive value when it is a negative value. I was wrong before - all three of the signs need to be switched. That is the problem with moving left that doesn't happen when you're moving right, because when you're moving right hspd is positive, so treating it like a positive value works.
Curiously, playing with the variables more made the player get stuck when walking right now. So I guess the problem isn't limited to that.

Thank you for your time.

EDIT: Oh well, I'll just find someone's tutorial and follow that.
 
Last edited by a moderator:

eimie

Member
That may not answer your actual question, but you could try the following code. With this code, your player should no longer get stuck in walls. If he does, it could at least be a clue to the solution to your problem:


GML:
if (_left && !_right) {
    dir = 1;
   
    if (sprite_index != spr_spdl) {
        sprite_index = spr_spdl;
    }
   
    if (!place_meeting(x - hspd, y, obj_block)) {
        hspd -= wspd;
    } else {
        while (!place_meeting(x - 1, y, obj_block)) {
            x--;
            hspd = 0;
        }
    }
} else if (!_left && _right) {
    dir = -1;
   
    if (sprite_index != spr_spdr) {
        sprite_index = spr_spdr;
    }
   
    if (!place_meeting(x + hspd, y, obj_block)) {
        hspd += wspd;
    } else {
        while (!place_meeting(x + 1, y, obj_block)) {
        x++;
        hspd = 0;
        }
    }
}
 
D

DarthTenebris

Guest
That may not answer your actual question, but you could try the following code. With this code, your player should no longer get stuck in walls. If he does, it could at least be a clue to the solution to your problem:


GML:
if (_left && !_right) {
    dir = 1;
  
    if (sprite_index != spr_spdl) {
        sprite_index = spr_spdl;
    }
  
    if (!place_meeting(x - hspd, y, obj_block)) {
        hspd -= wspd;
    } else {
        while (!place_meeting(x - 1, y, obj_block)) {
            x--;
            hspd = 0;
        }
    }
} else if (!_left && _right) {
    dir = -1;
  
    if (sprite_index != spr_spdr) {
        sprite_index = spr_spdr;
    }
  
    if (!place_meeting(x + hspd, y, obj_block)) {
        hspd += wspd;
    } else {
        while (!place_meeting(x + 1, y, obj_block)) {
        x++;
        hspd = 0;
        }
    }
}
Thanks for the help!
 
Top