13 Replies Latest reply on Jun 28, 2010 4:04 PM by 796262

Rotation...?

I'm making a game in java, basically like a Tower Defense game.

I've been working on this for 4 days now and its going pretty nicely.

I'm currently stuck with rotation, the rotation works but theres a issue...

The issue is that once the angle reaches 180 degrees and try's to increase more it'll instead go to -180.
I've been searching the internet for hourrrrrrss (a good 3 hours +)

Heres my code for rotation and setting rotation on a object:
``````                       //Setting of the rotations is only called when a new direction is required:
level.creep.setRequiredRotation(getDirectionDegree(level.creep[i].getMoveY()[currentTileMove + 1], level.creep[i].getY(), level.creep[i].getMoveX()[currentTileMove + 1], level.creep[i].getX()));
//Rotate the current rotation until we are at the required angle.
if(level.creep[i].getRotation() - level.creep[i].getRequiredRotation() > 10) {
level.creep[i].setRotation(level.creep[i].getRotation() - 10);
} else if(level.creep[i].getRotation() - level.creep[i].getRequiredRotation() < -10) {
level.creep[i].setRotation(level.creep[i].getRotation() + 10);
} else {
level.creep[i].setRotation(level.creep[i].getRequiredRotation());
}

public double getDirectionDegree(int y1, int y2, int x1, int x2) {
double direction = Math.toDegrees(Math.atan2(y1 - y2, x1 - x2));
return direction;
}
Heres a cleaner code that is used by towers:for(int i2 = 0; i2 < level.creep.length; i2++) {
if(level.creep[i2] != null) {
Rectangle towerRangeRectangle = new Rectangle((level.tower[i].getX() / Tile.TILE_SIZE - level.tower[i].getRange() / 2) * Tile.TILE_SIZE, (level.tower[i].getY() / Tile.TILE_SIZE - level.tower[i].getRange() / 2) * Tile.TILE_SIZE, level.tower[i].getRange() * Tile.TILE_SIZE, level.tower[i].getRange() * Tile.TILE_SIZE);
Rectangle creepRectangle = new Rectangle(level.creep[i2].getX(), level.creep[i2].getY(), Tile.TILE_SIZE, Tile.TILE_SIZE);
if(towerRangeRectangle.intersects(creepRectangle)) {
target = i2;
level.tower[i].setRequiredRotation(getDirectionDegree(level.creep[i2].getY(), level.tower[i].getY(), level.creep[i2].getX(), level.tower[i].getX()));
}
}
}
//Rotate the turret.
if(System.currentTimeMillis() - level.tower[i].lastTurretMoveTime >= 75) {
if(level.tower[i].getRotation() - level.tower[i].getRequiredRotation() > 10) {
level.tower[i].setRotation(level.tower[i].getRotation() - 10);
} else if(level.tower[i].getRotation() - level.tower[i].getRequiredRotation() < -10) {
level.tower[i].setRotation(level.tower[i].getRotation() + 10);
} else {
level.tower[i].setRotation(level.tower[i].getRequiredRotation());
}
level.tower[i].lastTurretMoveTime = System.currentTimeMillis();
}
Uses the same method to convert the radians to degrees as the top.
Does also the same basic thing as the top.

Help would be very appreciated. Thanks.

Edited by: steve4448 on Jun 21, 2010 7:22 PM                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                ``````
• 1. Re: Rotation...?
For better help sooner, post an [SSCCE |http://sscce.org] that demonstrates the problem. A single shape rotating (or whatever your problem looks like) in place would probably be sufficient.
• 2. Re: Rotation...?
(Hmm, can't edit my top post.. weird)
Okay heres a quickly made up SSCCE: (I made it into a 'game' so it shows the problem completely, hope this helps.)
``````import javax.swing.*;
import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.geom.AffineTransform;

public class Main extends JFrame {
//Okay, I made this SSCCE, all you have to do is start it and move
//around the center rectangle, once you completed a trip you'll notice it spins to -180 and to 180.
public static void main(String[] args) {
new Main();
}
public Main() {
super("My rotate example");
RotateSSCCE rotateSSCCE = new RotateSSCCE();
setResizable(false);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(800, 600);
setVisible(true);
}
}

class RotateSSCCE extends Component implements KeyListener, Runnable {
//Keys are WASD to move your rectangle
Rectangle rectangleDimension = new Rectangle(400, 300, 40, 20);
Rectangle rectangle2Dimension = new Rectangle(100, 300, 40, 20);
double requiredRectangleRotation;
double currentRectangleRotation;
public RotateSSCCE() {
}

@Override
public void paint(Graphics g) {
Graphics2D g2 = (Graphics2D) g;
//Work our rotation up until we meet the required rotation
//This is where the bug is, the bug will make the rotation 'reset' once it hits 180/-180 degrees
if(currentRectangleRotation - requiredRectangleRotation >= 5) {
currentRectangleRotation -= 5;
} else if(currentRectangleRotation - requiredRectangleRotation <= -5) {
currentRectangleRotation += 5;
}
AffineTransform aT = new AffineTransform();
aT.rotate(Math.toRadians(currentRectangleRotation), rectangleDimension.x + rectangleDimension.width / 2, rectangleDimension.y + rectangleDimension.height / 2);
g2.setTransform(aT);
g2.fillRect(rectangleDimension.x, rectangleDimension.y, rectangleDimension.width, rectangleDimension.height);
AffineTransform aT2 = new AffineTransform();
aT2.rotate(0.0); //Reset the rotation so it doesn't glitch this one, any other way to do this btw?
g2.setTransform(aT2);
g2.fillRect(rectangle2Dimension.x, rectangle2Dimension.y, rectangle2Dimension.width, rectangle2Dimension.height);
}

@Override
public void keyPressed(KeyEvent kE) {
if(kE.getKeyCode() == KeyEvent.VK_W) {
rectangle2Dimension.y -= 10;
} else if(kE.getKeyCode() == KeyEvent.VK_S) {
rectangle2Dimension.y += 10;
} else if(kE.getKeyCode() == KeyEvent.VK_A) {
rectangle2Dimension.x -= 10;
} else if(kE.getKeyCode() == KeyEvent.VK_D) {
rectangle2Dimension.x += 10;
}
requiredRectangleRotation = Math.toDegrees(Math.atan2(rectangle2Dimension.y - rectangleDimension.y, rectangle2Dimension.x - rectangleDimension.x));
}

@Override
public void run() {
while(true) {
repaint();
try {
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}

@Override
public void keyReleased(KeyEvent kE) {}

@Override
public void keyTyped(KeyEvent kE) {}
}``````
• 3. Re: Rotation...?
Maybe work through that, and see if there is anything you can apply to your code.
• 4. Re: Rotation...?
Sadly this isn't my problem I'm having, if you read my post I said I needed a rotation to gradually move up until its designated rotation.
So say if the rotation for the rectangle was 0, and the required rotation was 45, It would gradually plus until its reached its rotation.

In my post I mentioned I can do this fine (and if you used my SSCCE I posted, you'll notice what I mean)
but the issue is that once it hits -180/180 it practically 'resets' because of how the java rotation works.
• 5. Re: Rotation...?
steve4448 wrote:
In my post I mentioned I can do this fine (and if you used my SSCCE I posted, you'll notice what I mean)
but the issue is that once it hits -180/180 it practically 'resets' because of how the java rotation works.
No. It "resets" because of how your program logic works. Particularly these lines:
``````if(currentRectangleRotation - requiredRectangleRotation >= 5) {
currentRectangleRotation -= 5;
} else if(currentRectangleRotation - requiredRectangleRotation <= -5) {
currentRectangleRotation += 5;
}``````
Reexamine that logic.

Also, putting that stuff in your paint method (not to mention using paint instead of paintComponent) and calling repaint from a Thread is pretty ghetto. Try setting up a Timer instead.
• 6. Re: Rotation...?
What is wrong with my 'logic' in that code?
Also since this is a SSCCE I wasn't looking for having everything set-up like a real application, its just a demo application of whats wrong.
Theres nothing wrong with my rotation only that it "resets".
• 7. Re: Rotation...?
steve4448 wrote:
What is wrong with my 'logic' in that code?
If you don't understand what's happening, try adding some print lines to figure out what's going on.
Also since this is a SSCCE I wasn't looking for having everything set-up like a real application, its just a demo application of whats wrong.
That's fine, as long as you understand why the two things I listed are bad ideas.
Theres nothing wrong with my rotation only that it "resets".
Wouldn't that mean there's something wrong with it then?
• 8. Re: Rotation...?
kevinaworkman wrote:
steve4448 wrote:
What is wrong with my 'logic' in that code?
If you don't understand what's happening, try adding some print lines to figure out what's going on.
What exactly am I printing to the console?
I print out the operation (currentRectangleRotation - requiredRectangleRotation)
and I honestly don't see anything wrong with this.
Also since this is a SSCCE I wasn't looking for having everything set-up like a real application, its just a demo application of whats wrong.
That's fine, as long as you understand why the two things I listed are bad ideas.
Actually honestly I've never used paintComponent or a timer for doing this type of releated things.
Although I do my calculations in another void instead of the repaint method.
Theres nothing wrong with my rotation only that it "resets".
Wouldn't that mean there's something wrong with it then?
"Only that it "resets"", yes it does have a issue but I was stating that everything else was fine.

Thanks for posting btw, hopefully we can fix my fail of a problem :P.
• 9. Re: Rotation...?
steve4448 wrote:
You're welcome
Sadly this isn't my problem I'm having, if you read my post I said I needed a rotation to gradually move up until its designated rotation.
So say if the rotation for the rectangle was 0, and the required rotation was 45, It would gradually plus until its reached its rotation.
Well actually if you play around with this example you will see that he has solved your "reset" issue. Drag the mouse up and down past the 180/-180 lines and see that the objects continue to rotate in the same direction.

In my post I mentioned I can do this fine (and if you used my SSCCE I posted, you'll notice what I mean)
but the issue is that once it hits -180/180 it practically 'resets' because of how the java rotation works.
Your assumption that I didn't run your SSCCE is incorrect, but I'm not going to tell you what to change to fix it, I've given you a pointer to example code that has already solved your problem. It's up to you to understand that code, and the underlying issue, and to solve your problem based on that. If you still can't solve it, then at least show us that you have moved on a little bit, and ask further questions.

This isn't StackOverflow.com so you will find it less likely that people will give you complete solutions, they are more likely to give you hints/tips on how to solve your problem. I personally subscribe to this, as it gets you thinking critically, as opposed to just asking for the solution every time you hit a wall.
• 10. Re: Rotation...?
I never asked anyone to give me the complete fix.
I asked for a idea on what I'm doing wrong.
I can tell thats what you guys are trying to do but I'm not getting it...

I've tried to change my AfflineTransforms to what they have but it messed up my rotation, I don't see anything else different in my code other from than that though.
• 11. Re: Rotation...?
Your entire problem is in the if statements I pointed out in a previous post. Printing out the value of requiredRectangleRotation every time it's calculated helped me visualize what's going on. I think you already figured that part out, so what's stopping you from changing that if statement?

An easy first step towards a fix might be to figure out two separate cases instead: what do you want to do if the requiredRectangleRotation is negative? What if it's positive?

When you get that working, you can try to combine it into a single step.

Edit- Actually man, you've been a pretty good sport (better than many adults in your position) and I'm feeling generous today:
``````if(currentRectangleRotation < 0 ){
currentRectangleRotation += 360;
}
if(requiredRectangleRotation < 0 ){
requiredRectangleRotation += 360;
}
double deltaRotation = currentRectangleRotation - requiredRectangleRotation;
if(deltaRotation > 180){
deltaRotation -= 360;
}
else if(deltaRotation < -180){
deltaRotation += 360;
}

if(deltaRotation >= 5) {
currentRectangleRotation -= 5;
}
else if(deltaRotation <= -5) {
currentRectangleRotation += 5;
}``````
That seems to work. Enjoy.
• 12. Re: Rotation...?
Yay!

Thank you everyone for your time.

The code you gave me didn't work still, it basically flipped it so the other side was glitchy.
But than I noticed:
``````        if(currentRectangleRotation < 0 ){
currentRectangleRotation += 360;
}
if(requiredRectangleRotation < 0 ){
requiredRectangleRotation += 360;
}``````
and thought "Hey, shouldn't there be a clause for if its above 360 too?"
``````        if(currentRectangleRotation > 360){
currentRectangleRotation -= 360;
}
if(requiredRectangleRotation > 360){
requiredRectangleRotation -= 360;
}``````
and my rotation works 100% now.