Tower Image Rotation Fixes

If you have not read the previous topic I posted on this you may want to check it out, but that shouldnt be required. Anyway for my Tower Defense Game I can rotate a tower using this code:


			double angle = Math.atan2(targetY - pixY, targetX - pixX) * 180 / Math.PI;
			g2d.translate(x + Screen.room.blockSize / 2, y + Screen.room.blockSize / 2);
			g2d.rotate(Math.toRadians(angle - 270));
			g2d.drawImage(Screen.tileset_air[airID], -Screen.room.blockSize / 2, -Screen.room.blockSize / 2, Screen.room.blockSize, Screen.room.blockSize, null);
			g2d.dispose();

but something strange happens. It will rotate just fine at certain angles for example if the mob is coming from the left, but if it is coming from the top or right, the tower wont stay on target and will just slightly go up and then down and so on. Can anyone see any faults in this code?
Thanks, cMp

This is what I did in my particle system for Java2D and it work fine for rotation.


        Graphics2D g2d = (Graphics2D)g.create();
        g2d.setTransform(AffineTransform.getRotateInstance(rotation.x, loc.x, loc.y));

And of course dispose of the g2d. I never use the translate and rotation. Try that maybe?

What would fade, rotation.x, loc.x, loc.y be in my game? X and Y coords of tower, mob I am guessing, but what about fade?

The ‘fade’ variable stands for the level of ALPHA.
Ranges from 0.0 - 1.0 if I’m correct.
Has nothing to do with your issue though, from your opening post it doesn’t look like you have alpha implemented.

ah, thanks!

Cast to radians to degrees and then degrees to radians?
Does not seem an good implementation.


                        private static float correction = Math.toDegrees(270);  //Rotation fix

			double angle = Math.atan2(targetY - pixY, targetX - pixX);
			g2d.translate(x + Screen.room.blockSize / 2, y + Screen.room.blockSize / 2);
			g2d.rotate(angle - correction);
			g2d.drawImage(Screen.tileset_air[airID], -Screen.room.blockSize / 2, -Screen.room.blockSize / 2, Screen.room.blockSize, Screen.room.blockSize, null);
			g2d.dispose();

This is how I usually handle mine. ;D

Handles:
full 360D rotation if I’m correct.

Method for calculating the angle:


public double getAngleToTarget(double playerX, double playerY, double targetX, double targetY) {
	final double deltaX = (targetX - playerX);
	final double deltaY = (targetY - playerY);
	return Math.atan2(deltaY, deltaX);
}

Method for obtaining the angle:


final int centerX = absX + width / 2;
final int centerY = absY + height /2;
final double angle = getAngleToTarget(centerX, centerY, mouseX, mouseY);

Method for rendering with correct rotation:


final double theta = Math.toRadians(angle);
// Apply the rotation.
g2d.rotate(theta, x, y);
// Draw the image.
g2d.drawImage(img, x, y, null);
// Restore the rotation back to normal for other rendering.
g2d.rotate(-theta, x, y);

So for yours I’d do something like:


// Maybe (targetX, targetY, pixX, pixY)
final double angle = getAngleToTarget(pixX, pixY, targetX, targetY);
final double theta = Math.toRadians(angle);
g2d.rotate(theta, x, y);
g2d.drawImage(Screen.tileset_air[airID], -Screen.room.blockSize / 2, -Screen.room.blockSize / 2, Screen.room.blockSize, Screen.room.blockSize, null);
g2d.rotate(-theta, x, y);
g2d.dispose();

Hope this helps mate.

Ehh do not need that much code.

The rotation.x is the number of degrees you want to rotate by. Then the other two or the center coordinates of the sprite you are rotating. Once you find your angle in degrees just plug it into that method with your sprites location and bam. It does the translations I believe itself.

alright, in the rotate method, which x and y do you mean? The center of the tower?

I think I am going to stick with rotate because I know nothing of affine rotation and that. Thanks for trying though :slight_smile:

I guess your X and Y are both:


-Screen.room.blockSize / 2

According to:


g2d.drawImage(Screen.tileset_air[airID], -Screen.room.blockSize / 2, -Screen.room.blockSize / 2, Screen.room.blockSize, Screen.room.blockSize, null);

In my example my ‘x’ stood for my Images ‘x’.

lol, any further help needed? :o
Didn’t understand what you were saying, you got it figured out, or you just don’t want to use transforming.

Note: I don’t think I ever use graphics.translate() when dealing with rotation, I just revert the rotation back to normal.

Nah the x and y coords of tower is pixX and pixY, Screen.room.blocksize / 2 was used for positioning the image because rotate moves the image.

The location on the screen. So if you have an image at (200,200) you would use that.

AphineTransform just means that you are doing the rotation around that object as if the point you are giving it is the origin. What you are doing with the translate is basically an AphineTranform as you want the image to rotate around a different origin then the screen.

Here.


        Graphics2D g2d = (Graphics2D)g.create();
        double yourAngle = Math.atan2(targetY - pixY, targetX - pixX) * 180 / Math.PI;
        g2d.setTransform(AffineTransform.getRotateInstance(angle, pixX,pixY));
        g2d.dispose();

This assumes that your angle calculation gives the right angle.

This is funny, that code does the exact same thing as the old code did, rotates it fine from bottom and left, but when the mob comes from the top or right it just goes back and forth for about 45 degrees. Any ideas?

hmm…angle calc is off is my guess.


         rotation = (float) (FastMath.atan2(velocity.y, velocity.x) * (180/FastMath.PI));
	 rotation += 180;

Try this. FastMath is just a class for faster trig calls. You may need to change how much you add after the rotation. I do 180 as I want the particles to point from the left of the image. So if you have an image like this

[-----]
[-<–]
[-----]

it would keep the arrow pointing in the direction the image is going. If you have an image that is not pointing either left, right, up, or down then you will not get exact results as the source image is off. This is why if you look at most AAA games 2D textures they point in one direction not to an angle.

why are you using float when affinetransform uses doubles? I thought it was a mistake in your first post, but now I guess its for a reason

EDIT: I am the most stupid person on this earth. I was putting angle as a double data type. Good lord. Thank you very much for your help you have solved a problem I have been trying to fix for a VERY long time :slight_smile:

If you wouldn’t mind, off the top of your head what to you think a good way to rotate the image back to its starting position or next target once the mob is dead or out of range is?

Leave it ;D

Or if there is no mob in range just pass in 90, 180, 270 or w/e for its rotation.

Edit:
In that post I did it because that is actually opengl which takes floats.

haha ok man thanks for all your help