My latest game features an airplane being controlled by the user from a top-down perspective, flying over a spherical earth object. The airplane has the ability to rotate left or right by using the arrow keys on the keyboard, and can accelerate by pressing the UP arrow key. The airplane's direction and speed are determined by the user input, which is stored in the vx and vy variables.
In order to create the illusion of the airplane flying over the earth, the render loop utilizes the vx and vy variables to rotate the globe instead of moving the airplane itself.
However, a problem arises when the player reaches the opposite side of the globe; when the user flies to the right of the screen, the globe also rotates to the right, making it appear as though the airplane is flying backwards. This issue stems from attempting to incorporate old 2D code from a previous airplane game into this 3D game.
I believe that using quaternions may solve this problem, but I lack a full understanding of how to implement them. I think that my vx and vy variables could play a role in creating a "new location" vector. I have read about normalizing vectors, obtaining an axis and angle, but I am unsure of the specifics on how to achieve this. Any assistance on this matter would be greatly appreciated!
Below, you can find the code responsible for rotating the earth when the user flies in a specific x/y direction, along with an image to provide a better understanding of the game scenario.
// AIRPLANE VARIABLES
var friction = 0.85;
var vr = 7.5; // Rotation velocity
var thrust = 0.5;
var max_speed = 20;
var vx = 0; // X-velocity
var vy = 0; // Y-velocity
// RENDER LOOP
function render() {
// Check states
if (rotate_left) {
player.rotation.y = player.rotation.y + (vr * (Math.PI / 180));
} else if (rotate_right) {
player.rotation.y = player.rotation.y - (vr * (Math.PI / 180));
}
if(throttle){
var radians = player.rotation.y;
var ax = (Math.cos(radians) * thrust);
var ay = (Math.sin(radians) * thrust);
vx = vx + ax;
vy = vy + ay;
} else {
vx = vx * friction;
vy = vy * friction;
}
// Rotate the globe in the opposite direction of the airplane movement
globe.rotation.x = globe.rotation.x - (-vx/100);
globe.rotation.y = globe.rotation.y - (vy/100);
}