Affinetransform, rotating and coordinates after rotating
Hi,
I have been coding an Asteroids -like game. I have solved how to rotate the spaceship (which is triangle shaped), but now I noticed that the spaceship won't move like it should after rotating it. For example, if I rotate the ship clockwise for 90 degrees and then change it's y-coordinate (then it should move up or down, right?) instead of moving up/down it moves left/right. I think this has something to do spaceships own coordinates which rotates also.. So if you have some ideas how to change spaceships coordinates back to normal, please tell me.
Here is part of my code, I hope this is enough:
This one is from my paint component.
publicvoid paint(Graphics g){
Graphics2D g2 = (Graphics2D) g;
//Save the original At
saveXform = g2.getTransform();
//Set the color
g2.setColor(Color.white);
//Set the AT of the player
g2.setTransform(player.at);
//Draw the spaceship
player.drawSpaceship(g);
//Set the origina back
g2.setTransform(saveXform);
And these are from my Player-class, first is for painting and the other is for rotating
publicvoid drawSpaceship(Graphics g){
Graphics2D g2 = (Graphics2D) g;
//Draw the spaceship (which is a Shape)
g2.draw(spaceship);
}
//Rotate when left or right arrowkey is pressed
publicvoid Rotate(int degrees){
at.rotate(Math.toRadians(degrees), xPoints[2], yPoints[2]);
}
Message was edited by:
Janne88
[2101 byte] By [
Janne88a] at [2007-11-27 9:13:30]

# 1
import java.awt.*;
import java.awt.event.*;
import java.awt.geom.AffineTransform;
import javax.swing.*;
public class ClearTransmission extends JPanel {
SpaceShip spaceShip;
public ClearTransmission(JFrame f) {
spaceShip = new SpaceShip(100, 100, 0);
registerKeys(f);
setFocusable(true);
}
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D)g;
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
spaceShip.draw(g2);
}
private void registerKeys(JFrame f) {
JRootPane rp = f.getRootPane();
int c = JComponent.WHEN_IN_FOCUSED_WINDOW;
rp.getInputMap(c).put(KeyStroke.getKeyStroke("UP"), "UP");
rp.getActionMap().put("UP", upAction);
rp.getInputMap(c).put(KeyStroke.getKeyStroke("LEFT"), "LEFT");
rp.getActionMap().put("LEFT", leftAction);
rp.getInputMap(c).put(KeyStroke.getKeyStroke("DOWN"), "DOWN");
rp.getActionMap().put("DOWN", downAction);
rp.getInputMap(c).put(KeyStroke.getKeyStroke("RIGHT"), "RIGHT");
rp.getActionMap().put("RIGHT", rightAction);
rp.getInputMap(c).put(KeyStroke.getKeyStroke("A"), "A");
rp.getActionMap().put("A", antiClockwiseAction);
rp.getInputMap(c).put(KeyStroke.getKeyStroke("C"), "C");
rp.getActionMap().put("C", clockwiseAction);
}
public static void main(String[] args) {
JFrame f = new JFrame();
ClearTransmission space = new ClearTransmission(f);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.getContentPane().add(space);
f.setSize(400,400);
f.setLocation(200,200);
f.setVisible(true);
}
private void moveShip(int x, int y) {
spaceShip.move(x, y);
repaint();
}
private void turnShip(int direction) {
spaceShip.turn(direction);
repaint();
}
private Action upAction = new AbstractAction() {
public void actionPerformed(ActionEvent e) {
moveShip(0,-1);
}
};
private Action leftAction = new AbstractAction() {
public void actionPerformed(ActionEvent e) {
moveShip(-1,0);
}
};
private Action downAction = new AbstractAction() {
public void actionPerformed(ActionEvent e) {
moveShip(0,1);
}
};
private Action rightAction = new AbstractAction() {
public void actionPerformed(ActionEvent e) {
moveShip(1,0);
}
};
private Action antiClockwiseAction = new AbstractAction() {
public void actionPerformed(ActionEvent e) {
turnShip(-1);
}
};
private Action clockwiseAction = new AbstractAction() {
public void actionPerformed(ActionEvent e) {
turnShip(1);
}
};
}
class SpaceShip {
double x;
double y;
double theta;
double dx = 3.0;
double dy = 2.0;
double thetaInc = Math.toRadians(3);
Shape ship;
Color color = Color.red;
public SpaceShip(double x, double y, double theta) {
this.x = x;
this.y = y;
this.theta = theta;
createShip();
}
public void draw(Graphics2D g2) {
Rectangle r = ship.getBounds();
double cx = r.getCenterX();
double cy = r.getCenterY();
AffineTransform at = AffineTransform.getTranslateInstance(x, y);
at.rotate(theta, cx, cy);
g2.setPaint(Color.red);
g2.fill(at.createTransformedShape(ship));
}
public void move(int xInc, int yInc) {
x += xInc * dx;
y += yInc * dy;
}
public void turn(int direction) {
theta += direction * thetaInc;
}
private void createShip() {
int[] xpoints = {0, 10, -10 };
int[] ypoints = { -15, 10, 10 };
ship = new Polygon(xpoints, ypoints, 3);
}
}
# 2
Thank you, crwood! Now it works!
# 3
Hello, I'm here again with a little different problem..
Could someone show me (editing that code crwood posted for example) how to rotate a triangle and move it always to the direction of the sharpest edge of the triangle (for example).
The problem is that I can't handle coordinates (or shapes?) after rotating, so the triangle will always keep moving to the same direction after I have rotated it. It should instead look like the triangle would be turning it's direction but I can't make a good vector which would point the new direction after rotation.
Thank you for your time and effort in advance.
# 4
Switch to polar coordinates.
import java.awt.*;
import java.awt.event.*;
import java.awt.geom.AffineTransform;
import javax.swing.*;
public class ClearTransmission extends JPanel {
SpaceShip spaceShip;
public ClearTransmission(JFrame f) {
spaceShip = new SpaceShip(100, 100, 0);
registerKeys(f);
setFocusable(true);
}
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D)g;
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
spaceShip.draw(g2);
}
private void registerKeys(JFrame f) {
JRootPane rp = f.getRootPane();
int c = JComponent.WHEN_IN_FOCUSED_WINDOW;
rp.getInputMap(c).put(KeyStroke.getKeyStroke("UP"), "UP");
rp.getActionMap().put("UP", forwardAction);
rp.getInputMap(c).put(KeyStroke.getKeyStroke("A"), "A");
rp.getActionMap().put("A", antiClockwiseAction);
rp.getInputMap(c).put(KeyStroke.getKeyStroke("C"), "C");
rp.getActionMap().put("C", clockwiseAction);
}
public static void main(String[] args) {
JFrame f = new JFrame();
ClearTransmission space = new ClearTransmission(f);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.getContentPane().add(space);
f.setSize(400,400);
f.setLocation(200,200);
f.setVisible(true);
}
private void turnShip(int direction) {
spaceShip.turn(direction);
repaint();
}
private Action forwardAction = new AbstractAction() {
public void actionPerformed(ActionEvent e) {
spaceShip.move();
repaint();
}
};
private Action antiClockwiseAction = new AbstractAction() {
public void actionPerformed(ActionEvent e) {
turnShip(-1);
}
};
private Action clockwiseAction = new AbstractAction() {
public void actionPerformed(ActionEvent e) {
turnShip(1);
}
};
}
class SpaceShip {
double x;
double y;
double theta;
double d = 3.0;
double thetaInc = Math.toRadians(3);
Shape ship;
Color color = Color.red;
public SpaceShip(double x, double y, double theta) {
this.x = x;
this.y = y;
this.theta = theta;
createShip();
}
public void draw(Graphics2D g2) {
Rectangle r = ship.getBounds();
double cx = r.getCenterX();
double cy = r.getCenterY();
AffineTransform at = AffineTransform.getTranslateInstance(x, y);
at.rotate(theta, cx, cy);
g2.setPaint(Color.red);
g2.fill(at.createTransformedShape(ship));
}
public void move() {
// Angles in java start at 3 o'clock.
// We want angles to start at 12 o'clock
// in our view coordinate system. Use an
// offset of -90 degrees to translate from
// java to view reality.
x += d*Math.cos(theta-Math.PI/2);
y += d*Math.sin(theta-Math.PI/2);
}
public void turn(int direction) {
theta += direction * thetaInc;
}
private void createShip() {
int[] xpoints = {0, 10, -10 };
int[] ypoints = { -15, 10, 10 };
ship = new Polygon(xpoints, ypoints, 3);
}
}
# 5
Thank you so much, crwood! (Again!)I should have solved that by myself, but I was too confused about this new Affinetransform -thing and I didn't think about math...Thanks again!