How do I make smoother movement?

2019-09-08 09:23发布

问题:

So I need help to make my character move more smoothly. The problem is that the character moves one pixel when I press a key and after like one second he runs "smoothly" after that. How can I fix it so that I don't need to wait that one second and he just runs smoothly from the beginning? I appreciate any help and thanks before hand!

public void paintComponent(Graphics g)
{
    super.paintComponent(g);
    g.setColor(Color.GREEN);
    g.fillRect(x, y, 30, 30);
    update();
}
private boolean[] KB = new boolean[4];
public void update(){ 
    if(KB[0] = true)
    {
        y -= 10;
    }
    if(KB[1] = true)
    {
        x -= 10;
    }
    if(KB[2] = true)
    {
        y += 10;
    }
    if(KB[3] = true)
    {
        x +=10;
    }
    repaint();
}

public void keyPressed(KeyEvent e) {
    if(e.getKeyCode() == KeyEvent.VK_W)
    {
        KB[0] = true;
    }
    if(e.getKeyCode() == KeyEvent.VK_A)
    {
        x -= 10;
    }
    if(e.getKeyCode() == KeyEvent.VK_S)
    {
        y += 10;
    }
    if(e.getKeyCode() == KeyEvent.VK_D)
    {
        x += 10;
    }
}
public void keyReleased(KeyEvent e) {

}

public void keyTyped(KeyEvent e) {

回答1:

I would recommend against using KeyListener and recommand using the How to Use Key Bindings, it will solve the focus related issus with KeyListener and provide a much more reusable solution.

keyPressed will also have an initial delay when it's first pressed, between the first and repeating key strokes, this can be overcome by setting a flag when the key is pressed and released. See this example for more details

Don't call update in your paintComponent, painting may occur for any number of reasons, may of which you don't control, this could cause issues with maintaining a smooth animation.

Instead you need a "main" loop which is responsible for updating the state and scheduling repaints. As a simple solution, you could use a Swing Timer to do this, as it's to update the state of the UI from within without risking additional threading issues

Have a look at How to use Swing Timers for more details.

As has already been stated, use if(KB[0]) over if(KB[0] = true), as = is an assignment, not a evalution. Using the first form eliminates the possibility of accidentally making these kind og mistakes



回答2:

It is because your update method is incorrect. You use the = operator instead of == in your condition.

if (KB[0] = true)

will assign true to KB[0] and evaluate it as true, Therefore all your values will be set to true inside your if. Change = to == when you use it as a condition unless you want to assign the value.