g.fillRect(tankx, tanky, tank.width, tank.height);
? Когда tankx
или tanky
действительно изменяется?
Поскольку вы изменяете нижележащий контекст Graphics
в каждом цикле рисования, вы рискуете сложить вращение,Лучше использовать Graphics#create
, чтобы создать снимок текущего состояния, а затем изменить его.Просто не забудьте вызвать Graphics#dispose
для копии
Помните, что когда вы вращаете контекст Graphics
, вы также поворачиваете исходную точку (0x0), поэтому движение больше не будет "вверх" или "вниз ", но будет относительно угла поворота.
Итак, это модификация вашего кода.Я обновил метод paint
(вы действительно должны использовать paintComponent
), чтобы начало координат переводилось в положение танка (это делает 0x0
положение танка), тогда стало намного легчеповерните.
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
public class Rotate extends JPanel implements ActionListener, KeyListener {
Timer t = new Timer(20, this);
boolean right = false;
boolean left = false;
boolean up = false;
boolean down = false;
Rectangle tank;
int angle;
Rotate() {
JFrame f = new JFrame();
f.add(this);
f.addKeyListener(this);
f.setSize(1000, 1000);
f.setVisible(true);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
tank = new Rectangle(400, 400, 30, 50);
t.start();
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
new Rotate();
}
});
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
double radian = Math.toRadians(angle);
g2d.translate(tank.x, tank.y);
g2d.rotate(radian, tank.getWidth() / 2, tank.getHeight() / 2);
g2d.setColor(Color.red);
g2d.fillRect(0, 0, tank.width, tank.height);
g2d.dispose();
}
@Override
public void actionPerformed(ActionEvent e) {
if (right == true) {
angle += 4;
System.out.println("Right");
} else if (left == true) {
angle -= 4;
System.out.println("Left");
} else if (down == true) {
angle -= 4;
double radian = Math.toRadians(angle);
tank.x -= Math.cos(radian);
tank.y -= Math.sin(radian);
System.out.println("Down: " + tank.x + "x" + tank.y);
} else if (up == true) {
angle += 4;
double radian = Math.toRadians(angle);
tank.x += Math.cos(radian);
tank.y += Math.sin(radian);
System.out.println("Up: " + tank.x + "x" + tank.y);
}
repaint();
}
@Override
public void keyTyped(KeyEvent e) {
}
@Override
public void keyPressed(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_RIGHT) {
right = true;
} else if (e.getKeyCode() == KeyEvent.VK_LEFT) {
left = true;
} else if (e.getKeyCode() == KeyEvent.VK_UP) {
up = true;
} else if (e.getKeyCode() == KeyEvent.VK_DOWN) {
down = true;
}
}
@Override
public void keyReleased(KeyEvent e) {
right = false;
left = false;
up = false;
down = false;
}
}
Я также думаю, что вы cos
/ sin
повернули не в ту сторону, и вы должны вычесть вверх, а если добавить - вниз, но это исключительно на основе наблюдений.
Возможно, вы захотите взглянуть на:
для получения дополнительных идей