SOLVED Diagonal movement

Dev_M

Member
Hey fellow gamemakers!

My problem is the following. I have an object moving with speed 1 moving in direction 0.

STEP EVENT

x += x_lengthdir(1, 0);
y += y_lengthdir(1, 0);

So far so good! now I want the object to maintain constant speed, while being able to move it up or doen aswell.

if(arrow_up){
x += x_lengthdir(1, 90);
y += y_lengthdir(1, 90);
}

Once again so far so good, it moves diagonally forward. Now where my problem occurs is when I have diagonal constant movement, and need to be able to have the same turn angle and speed when turning.

STEP EVENT

x += x_lengthdir(1, 315); // Right bottom
y += y_lengthdir(1, 315); // Right bottom

So far so good, it moves diagonally right bottom.

if(arrow_right){
x += x_lengthdir(1, 315+90);
y += y_lengthdir(1, 315+90);
}

This dosent work, as when I hold the key, the object moves staight at direction 0, if I set vales to 45 degress,
it increases speed, which I dont want, I need to to maintin same as for horisont movement.

How do I go about this the right way for the diagnal movement and turning?


Dev_M
 

YoSniper

Member
How do you intend to steer the object, exactly? Maybe it would help if you drew a picture.

Is the object moving at a default speed, and you're applying a force to it? I am unsure what the problem looks like.
 

Dev_M

Member
How do you intend to steer the object, exactly? Maybe it would help if you drew a picture.

Is the object moving at a default speed, and you're applying a force to it? I am unsure what the problem looks like.
It has a constant speed in a certain direction using the lenghtdir function.

x += x_lengthdir(speed, direction);
y += y_lengthdir(speed, direction);


Then I can control it with arrow keys depening on which direction it is traveling.
My problem is with turning it when it travels diagonal, 45, 135, 225, 315.
Say it has a constant movement in direction 315 with a speed of 1 uring

x += x_lengthdir(1, 315);
y += y_lengthdir(1, 315);

And if I press the right arrow then I want it to turn +90 degress (after its constant movement).

x += x_lengthdir(1, 315+90);
y += y_lengthdir(1, 315+90);

And if I press left then -90 degress. Basically I want it behava the same way as it would with a simple diagonal turn of the
constant movement was just horisontal or vertical.
 
Trying to understand your post, it might just be me, but some things don't seem to add up.

if(arrow_up){
x += x_lengthdir(1, 90);
y += y_lengthdir(1, 90);
}

Once again so far so good, it moves diagonally forward. Now where my problem occurs is when I have diagonal constant movement, and need to be able to have the same turn angle and speed when turning.
How does this work? The code you posted would move the object straight up, yet you say it moves diagonally forward.

STEP EVENT

x += x_lengthdir(1, 315); // Right bottom
y += y_lengthdir(1, 315); // Right bottom

So far so good, it moves diagonally right bottom.

if(arrow_right){
x += x_lengthdir(1, 315+90);
y += y_lengthdir(1, 315+90);
}

This dosent work, as when I hold the key, the object moves staight at direction 0, if I set vales to 45 degress,
it increases speed, which I dont want, I need to to maintin same as for horisont movement.
Are you hardcoding the direction values or you have a direction variable you are updating? Or is this just for example? If you are hard-coding them, how are you separating all the movement commands so they don't conflict with each other?

How does using this code increase the speed? Unless you have multiple statements that are running at the same time, it should still move at a speed of 1 based on the code you have above.

Also, you said you want to move via the diagonals, but you are adding 90 to the direction, which is a right angle difference in direction.

Maybe you could post your entire Step code so we can see what's going on.
 

Dev_M

Member
STEP EVENT

x += lengthdir_x(player_speed, dir);
y += lengthdir_y(player_speed, dir);


switch(dir){

// Diagonal - down right, left
case 315:
if(keyboard_check(RIGHT)){
x += lengthdir_x(player_spee, dir+90);
y += lengthdir_y(player_spee, dir+90);
}
else if(keyboard_check(LEFT)){
x += lengthdir_x(player_spee, dir-90);
y += lengthdir_y(player_spee, dir-90);
}
break;
}


This is the case Im having problems with. there other controls aswell, but they arent relevant here since i
check the dir with switch which only enables the controls that I can use for that particular direction.

So at top the movement has already been done, then if I hold buttons I can turn 90 degress to either side
of the heading direction. What I mean with speed increasing is that, I already changed x and y, so when I
turn and change them again, the objects move once again within same step, therefore travel distance
is increased. how to go about this, to remove that extra travel distance but keep the same angilar turn as in.


switch(dir){

// Horizontal - up, down
case 0:
if(keyboard_check(RIGHT)){
x += lengthdir_x(player_spee, dir+90);
y += lengthdir_y(player_spee, dir+90);
}
else if(keyboard_check(LEFT)){
x += lengthdir_x(player_spee, dir-90);
y += lengthdir_y(player_spee, dir-90);
}
break;
}
 

YoSniper

Member
I think maybe your left and right are reversed?

It looks to me like your convention is this:

1. Object is moving in direction dir at speed player_spee

2. If the player presses the LEFT ARROW then the object also moves at speed player_spee 90 degrees counter-clockwise from dir
Similarly, if the player pressed the RIGHT ARROW then the object also moves at speed player_spee 90 degrees clockwise from dir.

If that's the case, then regardless of what dir is, this is a pictoral representation of what you are aiming for:

Code:
var xspeed, yspeed;
xspeed = player_spee * dcos(dir);
yspeed = -1 * player_spee * dsin(dir);

if keyboard_check(LEFT) {
    xspeed += player_spee * dcos(dir + 90);
    yspeed -= player_spee * dsin(dir + 90);
} else if keyboard_check(RIGHT) {
    xspeed += player_spee * dcos(dir - 90);
    yspeed -= player_spee * dsin(dir - 90);
}
Note that this MIGHT be the same result you already have, but now you have a (half-assed) picture to put it into perspective.

I work better with trigonometry than I do with the lengthdir functions, so it might take some getting used to.
 

Dev_M

Member
Code:
var xspeed, yspeed;
xspeed = player_spee * dcos(dir);
yspeed = -1 * player_spee * dsin(dir);

if keyboard_check(LEFT) {
    xspeed += player_spee * dcos(dir + 90);
    yspeed -= player_spee * dsin(dir + 90);
} else if keyboard_check(RIGHT) {
    xspeed += player_spee * dcos(dir - 90);
    yspeed -= player_spee * dsin(dir - 90);
}
Note that this MIGHT be the same result you already have, but now you have a (half-assed) picture to put it into perspective.

I work better with trigonometry than I do with the lengthdir functions, so it might take some getting used to.

Now I get the same results as in my code but its not right... let me explain it from another view...

Imagine we going in dir 0, just straight right, and if we push up arrow we should turn up but go right at the same time,
so now we have a diagonal movement... constant movement in dir 0 (right) and a turn movement up...

Now what I need is the same function to work properly when my constant movement is diagonal, and I turn also diagonally...
Do you understand how I mean?
 

Sabnock

Member
i use

if (keyboard_check(vk_right)) {
dir += turn_speed ;
}

if (keyboard_check(vk_left)) {
dir -= turn_speed;
}

hspd += dcos(dir) * .1;
vspd -= dsin(dir) * .1;

x += hspd;
y += vspd;

dir = direction the obj is facing in degrees.

in mine seems to work ok
 
Last edited:

Dev_M

Member
i use

if (keyboard_check(vk_right)) {
dir += turn_speed ;
}

if (keyboard_check(vk_left)) {
dir += turn_speed;
}

hspd += dcos(dir) * .1;
vspd -= dsin(dir) * .1;

x += hspd;
y += vspd;

dir = direction the obj is facing in degrees.

in mine seems to work ok
That code wont work for me, since its not the type of turnning I want, your seggestion is like a missle turn,
the turn I need is like in top down scroller, you have a constant movement, then if you hold right or left the object
still have its constant movement in dir, but also move twords the arrow key selected, and when you release the key
the object continues in its constant movement dir, so the constant movement dir does not chenge itself....

My code is working when my constant movement is dir = 0, 90, 180, 270, horisontal and vertical, my problem is getting
the same turn when constant movement is diagonal, so that it dosent increase overall distance traveled in comparison to
the movements mentioned above when turning. Since turning in diagonal will change x and y just as the constant movement does.
 

HayManMarc

Member
Are you trying to get basic 8-direction movement? (horizontal, vertical, diagonals) Do you want the direction of movement to change instantly or gradually?
 
the turn I need is like in top down scroller, you have a constant movement,
I'm still not sure i understand what kind of movement you mean.

Do you mean like a vertical shoot em up? Where the game world is scrolling automatically at a constant speed downwards, but you also want the player to move at a constant speed around the screen?

Do you have an example of a game that has the same type of movement that you want?
 

Joe Ellis

Member
The problem might be to do with turning towards an angle that's behind the current angle when it should be in front
like if the current angle is 359 and the target angle is 10, some things would make it turn backwards a whole 349 degrees,
I don't think thats the issue with this though, I don't know, just thought I'd throw that in there

But if anyone has that problem I mentioned, I use angle_difference, cus it gets to difference from one to another, within range of 180 to -180, so it overcomes those problems cause its relative to the current angle
 
Top