• Hey Guest! Ever feel like entering a Game Jam, but the time limit is always too much pressure? We get it... You lead a hectic life and dedicating 3 whole days to make a game just doesn't work for you! So, why not enter the GMC SLOW JAM? Take your time! Kick back and make your game over 4 months! Interested? Then just click here!

Legacy GM Movement & Collisions: Strafing and sliding along walls.

R

Robin326

Guest
Hello devs,

for some days now, I'm trying to find a solution for the following two problems, which I encounter in with my player movement. First of all, my code:

Code:
/// Player movement

// Movement direction
direction = point_direction(x, y, mouse_x, mouse_y);

// Facing direction
image_angle = direction;

// Move foreward
if keyboard_check(ord('W')){
speed = player_speed;
}
else speed = 0;

// Strafe left
if keyboard_check(ord('A')){
x -= lengthdir_x(player_speed, direction - 90);
y -= lengthdir_y(player_speed, direction - 90);
}

// Strafe right
if keyboard_check(ord('D')){
x -= lengthdir_x(player_speed, direction + 90);
y -= lengthdir_y(player_speed, direction + 90);
}

// Move backwards
if keyboard_check(ord('S')){
x -= lengthdir_x(player_speed * 0.75, direction);
y -= lengthdir_y(player_speed * 0.75, direction);
}

// Stop player when cursor position is reached
if point_distance(x, y, mouse_x, mouse_y) < 5{
speed = 0;
exit;
}
The code lets the player object move towards or in opposite direction of the cursor and lets it strafe to the left and right in a circular line. Top-Down shooter style.

First problem:
How can I strafe +/- 90 degrees from the player object facing direction, without using the circular line?

Second problem:
As soon as the player object collides with a wall, it stops. How can I make it slide along the walls?

I hope you guys can help me out.

Robin
 
This is a really strange movement system... so your character is always facing the cursor and they can either move towards it, away from it, or strafe in a circle around it? Weeeeeiiiirrrd.

Either way, you probably don't want to use the built in speed, direction, etc variables. They are all connected. If your speed drops to 0, for example, your direction will also drop to 0 (no movement equals no direction... although direction 0 is "right" so this is just stupid).

Since I don't see any collision checking here, I assume you are just using "solid" walls. Probably don't want to do that if you are going to be "sliding" along these walls. Wall sliding can be a very complicated problem depending on how precise you need them to be.

As for strafing around it, you need to use lengthdir to find the new point you want to move towards. So you find the direction from the cursor to the player, then find the point the same distance but 1 degree clockwise or counter clockwise depending on if the player is pressing left or right. Then have the player move towards that point at your desired speed.
 
R

Robin326

Guest
Hi there and thanks a lot for your reply!

I uploaded a short demonstration video:


I don't think this system is strange. Actually I do use the built in variables speed, room_speed and direction. I calculate the player movement speed with player_speed = room_speed * 0.05. Direction will not drop to zero, because the direction always refers to the cursor position. You can move forwards and backwards, while the player is moving towards or away from the cursor position. (Okay, maybe this is strange for the backwards movement. I will overthink to change this).

Collision checking happens in a collision event, which is not shown here. I'm using this without setting the walls or the player object to "solid". The player object uses a circle as a collision mask.

As you can see in the video clip, I figured out how to make the player slide along walls. I did this in the collision event with the function move_bounce_solid(false). A small issue with this, is that the player sometimes starts to shake a bit. I didn't figure out how to solve this and I think I'd need another collision system for this.

The strafing is indeed a problem and I can't figure out, how to properly use the lengthdir_x and lengthdir_y functions to make it work the way I want it to.
 
Top