您的示例代码有很多(最初)错误。
- 您正在覆盖该
paint
方法。建议您改写该paintComponent
方法。如果您要覆盖paint
顶级容器(如)的方法Jframe
,则建议您不要这样做。相反,使用类似的东西JPanel
作为自定义绘画的基础… - 您正在处理
Graphics
过去的上下文。这是非常危险的,因为这样可以防止其他东西被涂上。该Graphics
上下文是一个共享资源,一切都需要这个重绘周期中会使用相同的更新Graphics
内容。 - 您正在使用
KeyListener
。KeyListener
患有焦点问题。通过使用键绑定 API 可以很容易地对此进行补救。按键绑定还更加灵活,因为它们将物理按键与操作分开,使您可以轻松地将操作与不同的按键相关联和/或重用基础操作(如按钮)。
所以。你的问题。你得知道…
- 目前的速度…
- 最低允许速度…
- 最高允许速度…
您还需要保持要更改的对象的当前位置。
这个例子实际上并没有移动“玩家”,而是移动了背景。背景位置由改变
xDelta,即变化的速度…
import java.awt.BorderLayout;import java.awt.Color;import java.awt.Dimension;import java.awt.EventQueue;import java.awt.Graphics;import java.awt.Graphics2D;import java.awt.event.ActionEvent;import java.awt.event.ActionListener;import java.awt.event.KeyEvent;import java.awt.image.BufferedImage;import javax.swing.AbstractAction;import javax.swing.ActionMap;import javax.swing.InputMap;import javax.swing.Jframe;import javax.swing.JPanel;import javax.swing.KeyStroke;import javax.swing.Timer;import javax.swing.UIManager;import javax.swing.UnsupportedLookAndFeelException;public class TestSpeed { public static void main(String[] args) { new TestSpeed(); } public TestSpeed() { EventQueue.invokeLater(new Runnable() { @Override public void run() { try { UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) { } Jframe frame = new Jframe("Test"); frame.setDefaultCloseOperation(Jframe.EXIT_ON_CLOSE); frame.setLayout(new BorderLayout()); frame.add(new TestPane()); frame.pack(); frame.setLocationRelativeTo(null); frame.setVisible(true); } }); } public class TestPane extends JPanel { private BufferedImage background; // The current position of the background private int xPos = 0; // The speed/delta that the xPos is changed... private int xDelta = 0; public TestPane() { Timer timer = new Timer(40, new ActionListener() { @Override public void actionPerformed(ActionEvent e) { if (xPos < -(getWidth())) { xPos = 0; } xPos -= xDelta; repaint(); } }); timer.setRepeats(true); timer.setCoalesce(true); timer.start(); InputMap im = getInputMap(WHEN_IN_FOCUSED_WINDOW); im.put(KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, 0), "slower"); im.put(KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, 0), "faster"); ActionMap am = getActionMap(); am.put("slower", new AbstractAction() { @Override public void actionPerformed(ActionEvent e) { setSpeed(-1); } }); am.put("faster", new AbstractAction() { @Override public void actionPerformed(ActionEvent e) { setSpeed(1); } }); } protected void setSpeed(int delta) { xDelta += delta; // Check the change in speed to ensure it's within the appropriate range if (xDelta < 0) { xDelta = 0; } else if (xDelta > 9) { xDelta = 9; } } @Override public Dimension getPreferredSize() { return new Dimension(200, 200); } @Override public void invalidate() { background = null; super.invalidate(); } @Override protected void paintComponent(Graphics g) { super.paintComponent(g); int x = xPos; g.setColor(Color.DARK_GRAY); while (x < getWidth()) { g.drawLine(x, 0, x, getHeight()); x += 15; } int width = getWidth(); int height = getHeight(); x = (width / 2) - 5; int y = (height / 2) - 5; g.setColor(Color.RED); g.fillOval(x, y, 10, 10); } } }


