(Solved)Rotate Player movement with camera view rotation

JoeCruz

Member
So atm i can rotate the camera and the player matches the camera angle, im trying to add/subtract the angle of the camera view to the movement code of the player.
if i rotate the camera 180* and move the player up, it will actually be moving down, because its not taking into account the camera rotation. How could i go about implementing this rotation into the movement?


here's my player's step event:

GML:
// Inputs
right = keyboard_check(ord("D"));
left = keyboard_check(ord("A"));
up = keyboard_check(ord("W"));
down = keyboard_check(ord("S"));
close_game = keyboard_check(ord("R"));

var dirX, dirY, dir;

// Reset the direction
dirX = 0;
dirY = 0;

   
if (right || left)
    {
    dirX = right - left;
    }

if (up || down)
    {
    dirY = down - up;
    }


// Calculate the direction that the player needs to move
dir = point_direction(0, 0, dirX, dirY);

// Move the player

var currentSpeed = point_distance(0, 0, velocity[@ X], velocity[@ Y]);


// Horizontal movement
if (right || left)
{
   
    if (abs(currentSpeed) >= spd)
    {
        velocity[@ X] = lengthdir_x(spd, dir);
   
    }
    else
    {
        velocity[@ X] += lengthdir_x(acc, dir);
   
    }
}
else
{
    velocity[@ X] = lerp(velocity[@ X], 0, fric)
}

// Vertical movement
if (up || down)
{
    if (abs(currentSpeed) >= spd)
    {
       
        velocity[@ Y] = lengthdir_y(spd, dir);
           
    }
    else
    {
        velocity[@ Y] += lengthdir_y(acc, dir);      
    }
}
else
{
  velocity[@ Y] = lerp(velocity[@ Y], 0, fric)



}
variable for camera rotation is global.z and i just add or subtract to that by pressing Q/E to rotate it

Code:
//global cam angle
camera_set_view_angle(view_camera[0],global.z)

any help or tips would be appreciated :3
 

fishfern

Member
Just to clarify, are you looking to make it so that the player moves relative to the camera? If so, I'd try actually adding the angle of your camera to your 'dir' value/variable, so that the direction of the camera directly affects your lengthdir_x() and lengthdir_y() calculations. Generally speaking, an angle of '0' points towards the right of the room, so to get an accurate 'up' angle within GM, you would possibly need to add 90 degrees to your calculation.

Maybe try something like this?

GML:
dir = ((point_direction(0, 0, dirX, dirY)) + (global.z + 90));
This way (if my logic is okay), your angle calculations should then take both the keyboard and the camera rotation into account.

I hope this helps!
 

NightFrost

Member
Yes, the direction you want to accelerate into is the angle of movement from controls plus the angle of the camera. The result is the direction you want to accelerate into.

Incidentally, you are processing your axes separately, which means diagonal movement is faster. In case you want max speed be the same no matter the movement angle, you'd have to think movement as vectors. Your acceleration would be a vector [x,y] that has its vector length set to acceleration speed. This vector is added to your velocity vector [x,y] which is then clamped to vector length equal to your max speed.
 

JoeCruz

Member
Just to clarify, are you looking to make it so that the player moves relative to the camera? If so, I'd try actually adding the angle of your camera to your 'dir' value/variable, so that the direction of the camera directly affects your lengthdir_x() and lengthdir_y() calculations. Generally speaking, an angle of '0' points towards the right of the room, so to get an accurate 'up' angle within GM, you would possibly need to add 90 degrees to your calculation.

Maybe try something like this?

GML:
dir = ((point_direction(0, 0, dirX, dirY)) + (global.z + 90));
This way (if my logic is okay), your angle calculations should then take both the keyboard and the camera rotation into account.

I hope this helps!
thank you for the reply, ive tried changing the dir multiple times, including the code u wrote. it doesnt work, only in some directions at specific angles. I feel like each direction (awsd) needs to have its own algorithm


best result i got so far is
GML:
dir = ((point_direction(0, 0, dirX, dirY)) - (global.z));
using this, player movement works normally without rotating camera and if i invert it 180*player movement also works. but anywhere more or less than 180* or 0* and it bugs out
 
Last edited:

JoeCruz

Member
Yes, the direction you want to accelerate into is the angle of movement from controls plus the angle of the camera. The result is the direction you want to accelerate into.

Incidentally, you are processing your axes separately, which means diagonal movement is faster. In case you want max speed be the same no matter the movement angle, you'd have to think movement as vectors. Your acceleration would be a vector [x,y] that has its vector length set to acceleration speed. This vector is added to your velocity vector [x,y] which is then clamped to vector length equal to your max speed.
thank you for the reply! i have fixed the diagonal speed issue just didnt include it in the code ^^
 
Last edited:

NightFrost

Member
Sounds odd that it isn't working. I wrote a very simple test for myself (assumes camera follows player):
GML:
// PLAYER STEP

// Controls.
var _Up = keyboard_check(ord("W"));
var _Right = keyboard_check(ord("D"));
var _Down = keyboard_check(ord("S"));
var _Left = keyboard_check(ord("A"));
var _Cam_R = keyboard_check(ord("Q"));
var _Cam_L = keyboard_check(ord("E"));

// Camera rotation.
Cam_Angle += (_Cam_R - _Cam_L);
camera_set_view_angle(view_camera[0], Cam_Angle);

// Movement deltas.
var _DX = _Right - _Left;
var _DY = _Down - _Up;

if(_DX != 0 || _DY != 0){
    // Get direction.
    var _Dir = point_direction(0, 0, _DX, _DY);
    // Include camera angle.
    _Dir -= Cam_Angle;
    // Move player.
    x += lengthdir_x(Speed, _Dir);
    y += lengthdir_y(Speed, _Dir);
}

// PLAYER DRAW
draw_sprite_ext(sprite_index, 0, x, y, 1, 1, -Cam_Angle, c_white, 1);
And it works fine at any angle with WASD moving to correct directions.
 

JoeCruz

Member
Sounds odd that it isn't working. I wrote a very simple test for myself (assumes camera follows player):
GML:
// PLAYER STEP

// Controls.
var _Up = keyboard_check(ord("W"));
var _Right = keyboard_check(ord("D"));
var _Down = keyboard_check(ord("S"));
var _Left = keyboard_check(ord("A"));
var _Cam_R = keyboard_check(ord("Q"));
var _Cam_L = keyboard_check(ord("E"));

// Camera rotation.
Cam_Angle += (_Cam_R - _Cam_L);
camera_set_view_angle(view_camera[0], Cam_Angle);

// Movement deltas.
var _DX = _Right - _Left;
var _DY = _Down - _Up;

if(_DX != 0 || _DY != 0){
    // Get direction.
    var _Dir = point_direction(0, 0, _DX, _DY);
    // Include camera angle.
    _Dir -= Cam_Angle;
    // Move player.
    x += lengthdir_x(Speed, _Dir);
    y += lengthdir_y(Speed, _Dir);
}

// PLAYER DRAW
draw_sprite_ext(sprite_index, 0, x, y, 1, 1, -Cam_Angle, c_white, 1);
And it works fine at any angle with WASD moving to correct directions.
i have no idea what i did wrong i did the same thing with my variables and it didnt work, i used ur code and it worked perfectly, i mustve been changing the variables somewhere else in my code without knowng. thank you! solved
 
Top