我试图让逐渐精灵加速按下按钮,而不是只动恒定的速度。 也创下了最高速度的限制。 我希望你明白我的意思。
timer = new Timer(5, this);
timer.start();
public void paint(Graphics g) {
super.paint(g);
Graphics2D g2d = (Graphics2D)g;
g2d.drawImage(image, x, y, this); //x,y = position
Toolkit.getDefaultToolkit().sync();
g.dispose();
}
private class TAdapter extends KeyAdapter {
public void keyPressed(KeyEvent e) {
int key = e.getKeyCode();
if (key == KeyEvent.VK_LEFT) {
dx = -1;
}
if (key == KeyEvent.VK_RIGHT) {
dx = 1;
}
if (key == KeyEvent.VK_UP) {
dy = -1;
}
if (key == KeyEvent.VK_DOWN) {
dy = 1;
}
}
}
public void actionPerformed(ActionEvent e) {
x += dx;
y += dy;
repaint();
}
有几件事情(最初)不对您的示例代码...
- 您正在覆盖
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);
}
}
}
您需要定义和存储的值最大速度,实际速度和速度递增。 定义的速度递增,而应该首先尝试最简单的办法,就是定义一个恒定的速度递增。 根据所提供的代码:
int maxspeed = 5;
int speed = 1;
int acceleration = 1;
timer = new Timer(5, this);
timer.start();
public void paint(Graphics g) {
super.paint(g);
Graphics2D g2d = (Graphics2D)g;
g2d.drawImage(image, x, y, this); //x,y = position
Toolkit.getDefaultToolkit().sync();
g.dispose();
}
private class TAdapter extends KeyAdapter {
public void keyPressed(KeyEvent e) {
int key = e.getKeyCode();
if (key == KeyEvent.VK_LEFT) {
dx = -acceleration;
}
if (key == KeyEvent.VK_RIGHT) {
dx = acceleration;
}
if (key == KeyEvent.VK_UP) {
dy = -acceleration;
}
if (key == KeyEvent.VK_DOWN) {
dy = acceleration;
}
}
}
public void actionPerformed(ActionEvent e) {
if (speed < maxspeed) {
speed += acceleration;
}
x += dx * speed;
y += dy * speed;
repaint();
}
正如我真的不知道这个问题,还是目标实现的情况下,我不包括任何方式再次,以减缓下来的精灵一旦MAXSPEED被击中。
对速度的收益有些间隔也可以考虑。 与上面的代码中,更新速度将是速度不够快,你可能不会注意到他们。