[Solved] Rotation following Mouse

In my 2D game, I have a simple player sprite that moves with WASD. I want to make it rotate to follow my mouse, so the front of the sprite always points at the mouse. I know this is probably some advanced math, can anyone help?

Edit: Here is the final code we came up with:


// centerX and centerY are the center points of the sprite. playerX and playerY are the co-ordinates of the sprite.
float centerX = playerX + player.getWidth() / 2;
float centerY = playerY + player.getHeight() / 2;
         
float radiansToMouse = (float) Math.atan2(centerX - input.getMouseX(), centerY - input.getMouseY());
         
float degreesToMouse = (57.2957795f * radiansToMouse) * -1;
         
player.setRotation(degreesToMouse);

luckily for you I’ve done that not long ago :


public double computeAngle(Vector2f vec) {
       double distance = distance(0, 0, (int)vec.getX(), (int)vec.getY());
       double angle = getAngle(vec, new Vector2f(0,-1));
	if (vec.getX() < 0) angle *= -1;
	angle = Math.toDegrees(angle);
}

public double getAngle(Vector2f vec1, Vector2f vec2) {
	double distanceV1 = distance(0, 0, (int)vec1.getX(), (int)vec1.getY());
	double distanceV2 = distance(0, 0, (int)vec2.getX(), (int)vec2.getY());
		
	double angle = Math.acos((vec1.getX() * vec2.getX() + vec1.getY() * vec2.getY()) / (distanceV1 * distanceV2));
	return angle;
}

public double distance(int x1, int y1, int x2, int y2) {
	return Math.sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) *(y2 - y1));
}

Might be more efficient ways, or cleaner code. But this is what I managed to get after some thinking around and putting together math formulas. Vector2f is from le lwjgl package, but you can replace it with whatever implementation of a vector you want.

And this code works assuming that the player’s sprite is directed to the top of the image. If it’s not the case, change

new Vector2f(0,-1)

with the director vector of your sprite.

Btw, if others have tips to improve the efficiency / cleanliness of this code, I’d be grateful !

edit : Should of done this way before, but instead of using the function distance I put up there, I should of used

vec.length();

Going to change that straight away >.<
edit2: should of used Vector2f.dot(vec1,vec2) instead of rewriting it myself too.

Have done it lately in Arcane Nebula 1.0


float radiansToMouse = FastMath.atan2(sprite.centerY-mouseY, sprite.centerX-mouseX);
float degreesToMouse = 57.2957795f*radiansToMouse;
sprite.setRotation(degreesToMouse);

that angle is the angle you have to set your image’s rotation to.
all images should fact LEFT at 0 degrees, in file format… so your png or whatever should face left.

FastMath is just a faster Math Lib provided by Riven amoung others.
You can use any atan2 method; one is provided by the default Math class

Remember that if you have a camera / offset / more than one screen size, you have to offset the mouse/sprite location for the calculation

I look silly with my complicated stuff :frowning: Didn’t know about the atan2 function, much much simpler this way. I’ll replace my code with that, thanks !

This is great! Also, I accidentally found a way that you don’t need to make your sprites facing left. Here is my code:


float centerX = playerX + player.getWidth() / 2;
float centerY = playerY + player.getHeight() / 2;
		
float radiansToMouse = (float) Math.atan2(centerX - input.getMouseX(), centerY - input.getMouseY());
		
float degreesToMouse = (57.2957795f * radiansToMouse) * -1;
		
player.setRotation(degreesToMouse);

Actually, I’m just lazy as fuck, especially when there is Math; and I learned this method way back then by just asking =P

Yeah, actually I just checked, and “angle between two points” returns me the atan2 function in the first hit. The problem is (because I was working with vectors) I typed “angle between two vectors” which game me the formula with the dot product and stuff. Funny how things can change because you’re satisfied with the one result and don’t think there is anything simpler :slight_smile:

I’m glad we could all help eachother out here. Thanks for the replies! :slight_smile: