• 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!

GameMaker Changing Player's movement speed depending on direction

Q

qbot21

Guest
Hello :)

Im working on TDS prototype with a bit tactical approach. What I want to achieve, is that Player's speed is reduced, when he is moving backwards and making sidesteps depending on direction he is facing. Sadly I cannot solve it by myself. Im using point_direction to allow mouse aim.

Code:

Code:
// Step

var sec = delta_time/1000000;
var move_speed = floor(spd*sec);

var move_xinput = 0;
var move_yinput = 0;

direction = point_direction(x, y, mouse_x, mouse_y);
image_angle = direction;

for ( var i = 0; i < array_length_1d(movement_inputs); i++){
    var this_key = movement_inputs[i];
    if keyboard_check(this_key) {
        var this_angle = i*90;
        move_xinput += lengthdir_x(1, this_angle);
        move_yinput += lengthdir_y(1, this_angle);
    }
}

var moving = ( point_distance(0,0,move_xinput,move_yinput) > 0 );
if moving  {
    var move_dir = point_direction(0,0,move_xinput,move_yinput);
    move(move_speed, move_dir);
}
switch (state){
    case states.moving:
        spd = 180;
        
        if keyboard_check(run){
            state = states.run;
        }
        else if mouse_check_button(aim){
            state = states.aim;
        }
    break;
    case states.run:
        is_running = true;
        spd = 300;
        
        if !keyboard_check(run){
            state = states.moving;
            is_running = false;
        }
    break;
    case states.aim:   
        is_aiming = true;
        spd = 70;
        
        if !mouse_check_button(aim){
            state = states.moving;
            is_aiming = false;
        }
    break;
        
}

show_debug_message(move_speed);

Code:
// move script

var spd = argument0;
var dir = argument1;
 
var xtarg = x+lengthdir_x(spd,dir);
var ytarg = y+lengthdir_y(spd,dir);
 
if place_free(xtarg,ytarg) {
    x = xtarg;
    y = ytarg;
}
else {
    var sweep_interval = 10;
    
    for ( var angle = sweep_interval; angle <= 80; angle += sweep_interval) {
        for ( var multiplier = -1; multiplier <= 1; multiplier += 2) {     
            var angle_to_check = dir+angle*multiplier;
            xtarg = x+lengthdir_x(spd, angle_to_check);
            ytarg = y+lengthdir_y(spd, angle_to_check);     
            if place_free(xtarg,ytarg) {
                x = xtarg;
                y = ytarg; 
                exit;       
            }   
        }
    }
}
 
This might work (if I'm reading your code correctly)

They are facing towards the mouse coordinates, so if they are moving backwards then that is just the direction towards the mouse with 180 degrees added to it

Code:
if move_dir == direction + 180
{
is moving backwards, so change the speed
}
else
{
if move_dir == direction
{
is moving forwards, so speed is normal
}
}
If they are moving forwards then move_dir is the same as direction, and you would reset the speed back to normal. Then you'd want another condition for if they're strafing.

Code:
if move_dir == direction + 180 || move_dir == direction - 90 || move_dir == direction + 90
Something like that maybe, depending on whether backwards speed is the same as strafe speed.
 
Last edited:
Q

qbot21

Guest
Thanks, but that's doesn't seems to work :(
I think logic is good but there's something missing in code. Meaby I should somehow compare point_direction with Player's x and y not the direction itself?
 

woods

Member
as you are looking at the mouse while walking, you wont be moving +-90 in relation to forward.... more likely you would be rotating around where the mouse is while you are looking at it while strafing....

would that be why using direction isnt working?

edit:
couldnt you just add another state for strafing.. and adjust the speed from there like you do in walking running and aiming?
 
Last edited:
Code:
var move_dir = point_direction(0,0,move_xinput,move_yinput);
This does give a relative angle, and ought to be the same as

Code:
var move_dir = point_direction(x, y, x + move_xinput, y + move_yinput);
The origin point is different, but the relation to move_xinput / yinput (when added to the redefined origin point of x / y) won't change.

Code:
var move_xinput = 0;
var move_yinput = 0;

direction = point_direction(x, y, mouse_x, mouse_y);
image_angle = direction;

for ( var i = 0; i < array_length_1d(movement_inputs); i++){
    var this_key = movement_inputs[i];
    if keyboard_check(this_key) {
        var this_angle = i*90;
        move_xinput += lengthdir_x(1, this_angle);
        move_yinput += lengthdir_y(1, this_angle);
    }
}

var moving = ( point_distance(0,0,move_xinput,move_yinput) > 0 );
if moving  {
    var move_dir = point_direction(0,0,move_xinput,move_yinput);
    move(move_speed, move_dir);
}
My understanding of the code above is that:

move_xinput starts at 0

move_yinput " "

points towards mouse

loops through an array, which is storing details of keys

if a key is found to be pressed it sets this_angle to i * 90

So: this_angle = 0, 90, 180, 270, 360?

0 = right
180 = left
90 = up
270 = down ??

if that is the case then maybe using:

Code:
switch  (sign (y - y + move_yinput))
{case 1: // y is larger than y + move_input, so object is moving up

switch  (sign (y - mouse_y)
{case 1: // target is up, and it is the same as movement
player is facing forward, and moving forward;
break;
case -1: // target is down, and it is not the same as movement
player is facing down, but moving "backwards";
break;
}
break;

case -1: // y is less than y + move_input, so object is moving down

switch  (sign (y - mouse_y)
{case 1: // target is up, and it is not the same as movement
player is facing up, but moving "backwards";
break;
case -1: // target is down, and it is the same as movement
player is facing down, and moving "forwards";
break;
}
break;

case 0: // y is equal to y + move_input, so object is not moving up or down

switch  (sign (x - mouse_x)
{case 1: // target is left

switch  (sign (x - move_xinput)
{case 1: // movement is left
player is moving left, so is facing "forwards";
break;
case -1: // movement is right
player is facing left, so is moving "backwards";
break;

case -1: // target is right

switch  (sign (x - move_xinput)
{case 1: // movement is left
player is moving left, enemy is right, so is moving "backwards";
break;
case -1: // movement is right
player is facing right, moving right, and so is moving "forwards";
break;
}
break;
}
not sure if I've fully figured that out, or coded it totally correctly (as I haven't done it in a project, so there might be some brackets missing etc)
 
Q

qbot21

Guest
Thank you for ideas and sorry for late response. I had a lot thing to do in the project lately. I'll check the code shortly :)

Cheers!
 

JackTurbo

Member
I'd use angle difference between the move direction and the cursor direction. And base the movement speed off that.

something like (on my phone so excuse any mistakes):
Code:
var relativeMoveDir = abs(angle_difference(moveDir, cursorDir));

var directionSpd = relativeMoveDir /180 * (baseSpeed / 2);

actualSpeed = (baseSpeed / 2) + directionSpeed;
So this means when walking backwards you should move at half speed. Strafing would be 75% and forward would be 100%
 
Q

qbot21

Guest
@JackTurbo your code is working :D... almost. For some reason Player's speed while moving in mouse direction is decreased and if moving in opposite way, it's increased :/ Any idea what's going on?

I've made local var from point_direction for mouse rotation and used it as cursor_dir in your example and then called whole thing before move script. Could that messed up something?
 

JackTurbo

Member
When I said cursorDir a point direction from the player X/y to the mouse X/y is what I meant. So that should be fine.

The idea was to get the angle difference (which will be between 0-180) and convert that to a 0-1 value.

We then use that as a multiplier for half the movement speed and add that to a flat half of our movement speed to get a range from 50%-100%.

Not sure if I've got some of the logic backwards? Or if your point direction might be backwards?
*Edit* - I think I defo got some logic backwards

Just changinghe last bit from

Code:
actualSpeed = (baseSpeed / 2) + directionSpeed
To

Code:
actualSpeed = baseSpeed - directionSpeed
Should reverse it.

This gives a sliding scale of movement speeds. If you wanted set movement speeds for the directions that'd be achievable too using some different maths and either round or floor.
 
Last edited:
Top