0

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) {
Machavity
  • 30,841
  • 27
  • 92
  • 100
  • 4
    `if(KB[0] = true)` should be `if(KB[0] == true)` ? or just `if(KB[0])` – samgak May 08 '17 at 10:05
  • And why do you have a different logic in `keyPressed` ? PS : Calling repaint() in `paintComponent` is probably not the best idea either – AxelH May 08 '17 at 10:12
  • You need to use a `Swing Timer` to control the animation. See [Motion Using the Keyboard](https://tips4java.wordpress.com/2013/06/09/motion-using-the-keyboard/). The `KeyboardAnimation.java` example shows how to use a `Swing Timer` for smooth animation that you can control. – camickr May 08 '17 at 15:15

2 Answers2

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

Community
  • 1
  • 1
MadProgrammer
  • 343,457
  • 22
  • 230
  • 366
0

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.

Lajos Arpad
  • 64,414
  • 37
  • 100
  • 175
  • Ahh I see Thanks! It helped me out! btw do you know how I can use a timer in my code while your at it? would appreciate it since my teacher wants me to have one :D – Mushi Mushi May 08 '17 at 16:34
  • @MushiMushi you are welcome and you could take a look at this small tutorial: https://docs.oracle.com/javase/tutorial/uiswing/misc/timer.html. If my answer helped you solve your problem, then you might want to accept it as the correct answer. – Lajos Arpad May 08 '17 at 17:04