GameMaker Collision issue - Getting stuck in walls

W

Woodpig

Guest
Hey everybody! I'm new to Game Maker and therefore new to the forum as well.

My issue:
I'm making a simple 2D platformer prototype which I want to be able to expand upon in a number of platformer games. Therefore, I need the movement and the collision (everything really) to be rock solid. I feel like I'm getting pretty close but every now and then my character gets stuck in a wall. It just sucks.

It seems to happen when I'm moving down and into the wall at the same time. It doesn't happen too often, but it shouldn't happen at all in a perfect world. :(

If somebody could take a look at my code and help me identify the problem, that would be highly appreciated. This is the players step event.

Code:
//------------GET PLAYER INPUT

key_right_ = keyboard_check(ord("D")) || gamepad_button_check(4, gp_padr);
key_left_ = keyboard_check(ord("A")) || gamepad_button_check(4, gp_padl);
key_down_ = keyboard_check(ord("S")) || gamepad_button_check(4, gp_padd);
key_jump_ = keyboard_check_pressed(vk_space) || gamepad_button_check_pressed(4, gp_face1);
key_jump_held_ = keyboard_check(vk_space) || gamepad_button_check(4, gp_face1);
var _speed_wanted = 0;

//------------CALCULATE MOVEMENT

//Old movement code with no friction
/*var _move = key_right_ - key_left_;
x_speed_ = _move * walking_speed_;*/  

//Calculate horizontal movement

walljump_delay_ = max(walljump_delay_ - 1, 0);
if walljump_delay_ == 0 {

    //Walk right
    if key_right_ {
        _speed_wanted += walking_speed_;  
    }
    //Walk left
    if key_left_ {
        _speed_wanted -= walking_speed_;
    }

    //Smoothly accelerate
    x_speed_ += (_speed_wanted - x_speed_) * friction_;

}

//Walljump
if (on_wall_ != 0) && (!grounded_) && (key_jump_) {
    walljump_delay_ = walljump_delay_max_;
    x_speed_ = -on_wall_ * x_walljump_;
    y_speed_ = -y_walljump_;
    audio_play_sound(a_footstep1, 5, false);
    instance_create_layer(x, y, "Particles", o_dust);
}

//Calculate vertical movement
//Apply gravity at all times
var _gravity_final = gravity_;
var _y_speed_max_final = y_speed_max_;
if (on_wall_ != 0) && (y_speed_ > 0) {
    _gravity_final = gravity_wall_;
    _y_speed_max_final = y_speed_max_wall_;
}

y_speed_ += _gravity_final;
y_speed_ = clamp(y_speed_, -_y_speed_max_final, _y_speed_max_final);

//Jumping
jump_buffer_ -= 1;
if jump_buffer_ > 0 && key_jump_ {
    y_speed_ = -jump_force_;
    jump_buffer_ = 0;
    audio_play_sound(a_footstep1, 5, false);
    instance_create_layer(x, y, "Particles", o_dust);
}

//Release jump button for shorter jump
if y_speed_ < 0 && !key_jump_held_ {
    y_speed_ = max(y_speed_, -jump_force_/3);  
}

var _x_speed_final = x_speed_ + x_speed_carry_;
x_speed_carry_ = 0;

//Round the x_speed_ to an integer for pixel perfect collisions
var _xsp = round(_x_speed_final);
var _intentional_x_speed = round(x_speed_);

//Round the y_speed_ to an integer for pixel perfect collisions
var _ysp = round(y_speed_);

//Check for horizontal collision
if place_meeting(x+_xsp, y, o_collision) {
    while !place_meeting(x+sign(_xsp), y, o_collision) {
        x+=sign(_xsp);  
    }
    _xsp = 0;
    x_speed_ = 0;
}
x += _xsp;

//Check for vertical collision
if place_meeting(x, y+_ysp, o_collision) {
    while !place_meeting(x, y+sign(_ysp), o_collision) {
        y += sign(_ysp);
    }
    _ysp = 0;
    y_speed_ = 0;
}
y += _ysp;

//------------ANIMATION
grounded_ = place_meeting(x, y+1, o_collision);
on_wall_ = place_meeting(x+1, y, o_collision) - place_meeting(x-1, y, o_collision);

//Jump animation
if !grounded_ {
    if on_wall_ != 0 {
        sprite_index = s_player_wall;
        image_xscale = on_wall_;
       
        //Dust particles while wall sliding
        var _side = bbox_left;
        if on_wall_ == 1 {
            _side = bbox_right;
        }
        dust_++;
        if (dust_ > 2) && (_ysp > 0) {
            with instance_create_layer(_side, bbox_top, "Particles", o_dust) {
            other.dust_ = 0;
            hspeed = other.on_wall_ * 0.5;
            }
        }
    } else {
        dust_ = 0;
        sprite_index = s_player_jumping;
        image_speed = 0;
    }
    if sign(_ysp) < 0
    {
            //Moving up
        image_index = 0;  
    } else
    {
            //Moving down
            image_index = 1;
    }
} else {
    //Grounded
    jump_buffer_ = 6;
   
    //Landing
    if sprite_index == s_player_jumping && _ysp >= 0 {
        audio_sound_pitch(a_landing, choose(0.8, 1.0, 1.4, 1.6));
        audio_play_sound(a_landing, 4, false);
        instance_create_layer(x, y, "Particles", o_dust);
    }
   
    image_speed = 1;
   
    //Running
    if key_right_ || key_left_ != 0 {
        sprite_index = s_player_running;
       
        //Step sound effects
        if floor(image_index) == 3 && !audio_is_playing(a_footstep3) {
            audio_sound_pitch(a_footstep3, 1.2);
            audio_play_sound(a_footstep3, 3, false);
        }
        if floor(image_index) == 7 && !audio_is_playing(a_footstep3) {
            audio_play_sound(a_footstep3, 3, false);
        }
    } else {
        //Player idle
        sprite_index = s_player_idle;
        image_speed = 1;
    }
}
//Flip the sprite
if x_speed_ != 0 {
    image_xscale = sign(x_speed_);
}
Also: if something looks crazy in there in general. Feel free to point my mistakes out. I'm in this to learn. :)
 
Top