So, now I've got into my second problem of implementing the arrow. The rotation works fine from this link but I have to calculate the angle from a touch point to the middle of the arrow placement.
I've already calculated that angle, well if I'm not mistaken. I used a vertical distance that is just the touch points y coordinate since the center y coordinate is 0. For the x coordinate I subtracted the touch point minus the texture regions x coordinate in draw function.
Then to calculate the angle I used arcus tangent inside divided the vertical length by the horizontal length, then multiplied by 180 / PI to get the angle in degrees.
The thing is that this worked a bit like I wanted, but not exactly. Because when taking the touch points coordinates and bottom center coordinates the invisible triangle that is created will be created as a mirrored triangle on the half side of the screen. Meaning when going over to the other side with a finger the angle was negative. Tried using a the math absolute function but then the arrow bounced back when it reached the angle limit.
Draw function:
@Override
public void draw(SpriteBatch spriteBatch) {
spriteBatch.setProjectionMatrix(EtherSky.camera.combined);
spriteBatch.begin();
spriteBatch.draw(textureRegion,
x - textureRegion.getRegionWidth() / 2, y,
textureRegion.getRegionWidth() / 2, 0,
textureRegion.getRegionWidth(),
textureRegion.getRegionHeight(),
1.0f, 1.0f, degrees);
spriteBatch.end();
}
Input function:
@Override
public void input() {
/*
if (Gdx.input.getAccelerometerX() > 3 && degrees < 90) {
degrees++;
}
else if (Gdx.input.getAccelerometerX() < -3 && degrees > -90) {
degrees--;
}*/
// Distance from arrow bottom center point to touch point
float distance = (float)Math.sqrt(
Math.pow((inputManager.touchPoint.x - (x - textureRegion.getRegionWidth() / 2)), 2) +
Math.pow((inputManager.touchPoint.y - 0), 2));
float verticalDistance = inputManager.touchPoint.y;
float horizontalDistance = inputManager.touchPoint.x - (x - textureRegion.getRegionWidth() / 2);
float angle = (float)Math.abs(Math.atan(verticalDistance / horizontalDistance) * 180 / Math.PI);
if (Gdx.input.isTouched()) {
degrees = angle;
}
System.out.println("Player (" + Gdx.input.getX() + ", " + Gdx.input.getY() + ")");
System.out.println("Degrees: " + degrees + " Angle: " + angle);
}
The black dots on the image represents touch points and this is what the invisible triangles would look like if I'm not imagining wrongly.
Example image:
UPDATED CODE
float verticalDistance = inputManager.touchPoint.y;
float horizontalDistance = inputManager.touchPoint.x - x; // (x - textureRegion.getRegionWidth() / 2)
float angle = (float)Math.toDegrees(Math.atan2(verticalDistance, horizontalDistance)) - 90;
if (Gdx.input.isTouched()) {
degrees = angle;
if (degrees < 90)
degrees = 89;
}
I tried to do this but it doesn't work because then I get the arrow stuck at 89 degrees forever. Notice that this is not the arrow pointing straight up, it's the arrow pointing to the left.
I am aware why the code doesn't work but I don't know how to get it to work.
UPDATED CODE FOR FUTURE READERS (ANSWER)
private void inputFollowFinger() {
float verticalDistance = inputManager.touchPoint.y;
float horizontalDistance = inputManager.touchPoint.x - x;
float angle = (float)Math.toDegrees(Math.atan2(verticalDistance, horizontalDistance)) - 90;
if (Gdx.input.isTouched()) {
degrees = angle;
arrowStayAt90Degrees();
}
}
private void arrowStayAt90Degrees() {
final int stayAtDeg = 90;
final int adjustDeg = 180;
if (degrees < -adjustDeg) {
degrees = stayAtDeg;
}
else if (degrees < -stayAtDeg) {
degrees = -stayAtDeg;
}
}
-90
, the test should be:if(degrees < -180) { degrees = 90; } else if(degrees < -90) { degrees = -90; }
\$\endgroup\$