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.
Also: if something looks crazy in there in general. Feel free to point my mistakes out. I'm in this to learn.
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_);
}