0

I am trying to create a walking animation. It should alternate between playerLeft and playerLeftWalk. The code is shown below:

public class MyClass extends JPanel implements ActionListener, KeyListener{
    protected Timer tm = new Timer(10, this);
    protected Clip clip;
    protected Image background, playerSprite, playerLeft, playerLeftWalk;
    protected int mapdx = 0;
    protected int mapdy = 0;
    protected int mapX = 0;
    protected int mapY = 0;
    protected int playerX = 1060;
    protected int playerY = 2800;
    protected volatile boolean activeThread;

    @Override
    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        g.drawImage(this.background, this.mapX + this.mapdx, this.mapY - this.mapdy, this);
        g.drawImage(this.playerSprite, this.playerX, this.playerY, this);
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        mapX += mapdx;
        mapY += mapdy;
        this.repaint();             
    }

    @Override
    public void keyPressed(KeyEvent e) {
        int k = e.getKeyCode();

        Thread playerControl=null;
        if (!activeThread) {
            this.activeThread=true;
            playerControl = new Thread(new Runnable() {
                @Override
                public void run() {
                    switch (k) {
                    case KeyEvent.VK_LEFT:
                        mapdx = 1;
                        mapdy = 0;
                        System.out.println("Map X: " + mapX + " Map Y: " + mapY);
                        try {
                            playerSprite = playerLeftWalk;
                            Thread.sleep(250);
                            playerSprite = playerLeft;
                        } catch (InterruptedException e) {
                        }
                        break;

                    default:
                        break;
                    }
                }
            });
            activeThread=false;
        }   
        if(playerControl!=null)
            playerControl.start();
    }

    @Override
    public void keyReleased(KeyEvent e) {
        int k = e.getKeyCode();
        if(k == KeyEvent.VK_LEFT) {
            mapdx = 0;
            mapdy = 0;
            playerSprite = playerLeft;
        }
    }

    @Override
    public void keyTyped(KeyEvent e) {
    }
}

What the code above does is work for the first "cycle" and then stutter thereafter. I assume that what is happening is that multiple threads are being created, making the image stutter.

Razonixx
  • 15
  • 2
  • As a general rule, `KeyListener` is a bad choice, make use of the [keybindings API](https://docs.oracle.com/javase/tutorial/uiswing/misc/keybinding.html) instead. Instead of using threads like this, you should have a "main loop" which processes the key states and updates the model state of what ever you trying to render, it should then render the output – MadProgrammer Oct 30 '17 at 19:38
  • [For example](https://stackoverflow.com/questions/34146965/java-swing-key-input-with-jpanel-added-to-joptionpane/34147249#34147249) and [example](https://stackoverflow.com/questions/23463174/getting-my-sprite-to-face-in-a-certain-direction-based-on-keyboard-input-java/23463387#23463387) – MadProgrammer Oct 30 '17 at 19:39
  • Will check them out, thanks! – Razonixx Oct 30 '17 at 20:01
  • And finally [one of the examples I've been locking for](https://stackoverflow.com/questions/24522458/flipping-rotations-and-images/24523176#24523176) and [something little bit closer to what you're doing](https://stackoverflow.com/questions/23860755/how-to-change-images-based-on-keystrokes/23861786#23861786) – MadProgrammer Oct 30 '17 at 20:26

0 Answers0