Java:使用KeyPress以一定角度移动对象并改变角度

好吧,所以我想要的是矩形始终在移动,但是当你按下左右箭头时,通过增大或减小角度来改变方向。 使用此代码,sqaure按正确的方向移动,但是当我按下按键时,方向不会改变。

import java.awt.*; import java.awt.Color; import javax.swing.Timer; import javax.swing.*; import java.awt.Graphics; import java.awt.event.ActionListener; import java.awt.event.ActionEvent; import java.awt.event.KeyListener; import java.awt.event.KeyEvent; import java.awt.event.KeyAdapter; public class Fields extends JPanel implements ActionListener, KeyListener{ Timer tm = new Timer(5, this); double x = 250, y = 250, vel = 0.2, angle = 90; public void paintComponent(Graphics g) { super.paintComponent(g); this.setBackground(Color.BLACK); g.setColor(Color.GREEN); g.fillRect((int)x, (int)y, 5, 5); tm.start(); } public void keyTyped(KeyEvent e) { if (e.getKeyCode() == 37) {angle--;} if (e.getKeyCode() == 39) {angle++;} } public void keyReleased(KeyEvent e) { if (e.getKeyCode() == 37) {angle--;} if (e.getKeyCode() == 39) {angle++;} } public void keyPressed(KeyEvent e) { if (e.getKeyCode() == 37) {angle--;} if (e.getKeyCode() == 39) {angle++;} } public void actionPerformed(ActionEvent e) { x += (velX * (float)Math.cos(Math.toRadians(angle - 90))); y += (velX * (float)Math.sin(Math.toRadians(angle - 90))); repaint(); } public Fields() { this.addKeyListener(this); } public static void main(String[] args) { JFrame f = new JFrame(); f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); f.setSize(500, 500); Fields fi = new Fields(); f.add(fi); f.setVisible(true); } } 

正如我的评论中所述……

  • 不要在paintComponent启动计时器,重复调用此方法,并且可以快速连续调用。
  • 使用键绑定

 public class TestAnimation01 { public static void main(String[] args) { new TestAnimation01(); } public TestAnimation01() { EventQueue.invokeLater(new Runnable() { @Override public void run() { try { UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); } catch (ClassNotFoundException ex) { } catch (InstantiationException ex) { } catch (IllegalAccessException ex) { } catch (UnsupportedLookAndFeelException ex) { } JFrame frame = new JFrame(); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setLayout(new BorderLayout()); frame.add(new Fields()); frame.setSize(400, 400); frame.setLocationRelativeTo(null); frame.setVisible(true); } }); } public class Fields extends JPanel implements ActionListener { Timer tm = new Timer(125, this); double x = 250, y = 250, vel = 0.2, angle = 90; private int velX = 4; private int velY = 4; @Override public void paintComponent(Graphics g) { super.paintComponent(g); this.setBackground(Color.BLACK); g.setColor(Color.GREEN); g.fillRect((int) x, (int) y, 5, 5); } public void actionPerformed(ActionEvent e) { x += (velX * (float) Math.cos(Math.toRadians(angle - 90))); y += (velX * (float) Math.sin(Math.toRadians(angle - 90))); repaint(); } public Fields() { setFocusable(true); InputMap im = getInputMap(WHEN_FOCUSED); ActionMap am = getActionMap(); // left 37 im.put(KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, 0), "goLeft"); im.put(KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, 0), "goRight"); am.put("goLeft", new AbstractAction() { @Override public void actionPerformed(ActionEvent e) { angle--; repaint(); } }); am.put("goRight", new AbstractAction() { @Override public void actionPerformed(ActionEvent e) { angle++; repaint(); } }); tm.setRepeats(true); tm.setCoalesce(true); tm.start(); requestFocusInWindow(); } } } 

还有很多其他你没有涉及的东西,比如边缘条件(当它离开屏幕时会发生什么)和单独的x / y速度,但我相信你会解决它