Search code examples
javalibgdxangle

Java LibGDX relative value addition based on angle and position


I create a 2d game similar to a classic diepio. I created a system for positioning the player's barrel in a specific direction. The updated angle is sent to the server. When the player clicks, the server creates a missile. This only works correctly when the barrel is attached to the center of the player's body. When I want to move the barrel away from the center of the body, there is a problem. I don't know how to update the server-side position where the projectile spawns.

In the image below, the barrel rotates around the center of the player's body. I marked the missile's flight path with the red line.
image1

On this image, the barrels also have a rotation axis in the player's center, but have been shifted to the side. The green line marked the route the missile should take. Unfortunately, I don't know how to do it correctly.
image2

How to update the projectile's spawn point by a given distance (e.g. 10) from the basic distance (if the barrel was not moved) based on the player's angle of rotation and his position?

Projectile spawn method:

float angle = (float) ((player.getRotation() + 90) * Math.PI / 180f);

float forceX = (float) Math.cos(angle);
float forceY = (float) Math.sin(angle);

spawnProjectile(player.getPosition().x + (forceX * 3f), player.getPosition().y + (forceY * 3f));

Solution

  • If I understood your question correctly, you want to find the two points marked in orange in the following image:

    enter image description here

    Since you know the direction in which the missiles should fly (the red line), the distance from the center position (e.g. 10) and you know that there is a 90° angle between the movement vector of the missile (red line) and the connection line between the two starting positions of the missiles (marked as black line in the image) you can calculate the resulting positions like this:

    float angle = (float) ((player.getRotation() + 90) * Math.PI / 180f);
    
    float forceX = (float) Math.cos(angle);
    float forceY = (float) Math.sin(angle);
    
    // the center point (start of the red line in the image)
    float centerX = player.getPosition().x + (forceX * 3f);
    float centerY = player.getPosition().y + (forceY * 3f);
    
    float offsetFromCenterDistanceFactor = 1f; // increase this value to increase the distance between the center of the player and the starting position of the missile
    
    // the vector towards one of the starting positions
    float offsetX1 = forceY * offsetFromCenterDistanceFactor;
    float offsetY1 = -forceX * offsetFromCenterDistanceFactor;
    
    // the vector towards the other starting position
    float offsetX2 = -offsetX1;
    float offsetY2 = -offsetY1;
    
    //spawn the upper missile
    spawnProjectile(centerX + offsetX1, centerY + offsetY1);
    //spawn the lower missile
    spawnProjectile(centerX + offsetX2, centerY + offsetY2);
    

    For more detail on the calculation of the orthogonal vectors see this answer.