I'm making a 2D game in Java where the player guides a polygon through obstacles. The polygon moves up and down and the game world scrolls left and right. I need the polygon to rotate around its center, but since it is constantly being translated the point it is being rotated around moves. Trying to translate it back to the original center, rotate it, and translate it back doesn't work. How do I get the center of the shape?
Here are my motion calculations on a 2ms timer:
@Override
public void actionPerformed(ActionEvent e) {
double theta = angleRad+90;
if (up == true) {
if (accelerating == false) {
time2 = 0;
moveX0 = moveX;
moveY0 = moveY;
accelerating = true;
}
time1++;
double t = time1/500;
if (accCount % 10 == 0) {
DronePilot.velocity++;
}
moveX = moveX0 + velX*Math.cos(theta)*t;
moveY = moveY0 + velY*Math.sin(theta)*t-(1/2d)*g*Math.pow(t, 2);
velX = (DronePilot.velocity)*Math.cos(theta);
velY = (DronePilot.velocity)*Math.sin(theta)-g*(t);
accCount++;
} else if (up == false){
if (accelerating == true) {
time1 = 0;
moveX0 = moveX;
moveY0 = moveY;
accelerating = false;
}
time2++;
double t = time2/500;
moveX = moveX0 + velX*Math.cos(theta)*t;
moveY = moveY0 + velY*Math.sin(theta)*t-(1/2d)*g*Math.pow(t, 2);
accCount = 0;
} if (left == true) {
angleCount++;
if (angleCount % 2 == 0) {
angleDeg++;
}
angleRad = Math.toRadians(angleDeg);
} else if (right == true) {
angleCount--;
if (angleCount % 2 == 0) {
angleDeg--;
}
angleRad = Math.toRadians(angleDeg);
}
repaint();
}
}
And here is my paintComponent method:
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2D = (Graphics2D)g;
Graphics g2 = g.create();
Graphics2D copy = (Graphics2D)g2;
copy.rotate(-angleRad, xPos, yPos);
copy.translate(0, -moveY);
g2D.translate(-moveX, 0);
copy.draw(player.shape);
for (Rectangle2D.Double r: DronePilot.rocksFloorArray) {
g2D.draw(r);
}
for (Rectangle2D.Double r: DronePilot.rocksCeilArray) {
g2D.draw(r);
}
for (Rectangle2D.Double r: DronePilot.roomsArray) {
g2D.draw(r);
}
}
where (xPos, yPos) are the center of the screen.
In openGL we save transformation state using
pushMatrix()
andpopMatrix()
. Here their equivalents areGraphics.create()
andGraphics.dispose()
Transformations are (normally) compounding
In your above code, you are translating both the original
Graphics
context and thecopy
. In this context,copy
won't be affected by the original and the original won't be affected by thecopy
, BUT, the original context is a shared resource and since you don't reset the translation, you will continue to get a translated context each time (compounding).As a general rule of thumb, do ALL transformations on a copy and dispose of it when you're done.
For example...
This basically translates the position of the object to the player's position and then rotates the object about the centre of the object
You could, also, apply one transformation, create a copy of that context and apply another transformation, which would become compounded (so you could
translate
one context, copy it, and thenrotate
the copy and the first translation would still applied to the copy)This incredible simple example demonstrates two basic example...
Graphics
context and aAffineTransform
to translate and rotate the player object (about it's centre point)Path2D
to generate a transformed shape (this example makes two objects, but you could use a singleAffineTransform
translated and rotated and apply it once).In both cases, they don't affect the original shape