在Java游戏中同步两个线程之间的键盘输入

时间:2015-03-26 15:57:51

标签: java multithreading

我目前正在开发一款Java格斗游戏,但我遇到了障碍。

基本上我有两个线程在运行:一个由Canvas实现,它可以更新绘制到屏幕的所有内容然后休眠;一个由字符类实现的,只是更新字符的位置。我还在Canvas类中有一个实现KeyListener的子类,并为任何键的状态更改更改了一个布尔变量,如果按下向上按钮,则更新字符自己的up布尔变量。

我的问题是,当我按下键盘上的按钮时,输入肯定会在Canvas端进行(我已经用print语句确认了它),但它并不总是通过角色,我可以解决的问题由于角色的位置更新在一个单独的线程中运行,因此只会假设正在出现。

这是我的相关代码:

//
public class GameWindow extends Canvas implements Runnable {
    ...
    private KeyInputManager input; //Just implements KeyListener
    private Thread animator;
    private Character player1; //My character class
    ...

    public GameWindow() {
        ...
        input = new KeyInputManager();
        player1 = new Character();
        animator = new Thread(this);
        animator.start();
        ...
    }

    ...

    public void run() { //This is in the Canvas class
        while (true) {
            if (input.isKeyDown(KeyEvent.VK_UP) {
                character.upPressed = true;
            }
            ...
            player1.updateImage(); //Update the character's graphics
            gameRender(); //Draw everything
            try {
                Thread.sleep(10);
            catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
    ...
}

public class Character implements Runnable {
    ...
    Thread myThread;
    ...

    public Character() {
        ...
        myThread = new Thread(this);
        myThread.start();
        ...
    }

    ...

    public void run() {
        if (upPressed) {
            //This is where all my jumping code goes
            //Unfortunately I barely ever get here
        }
        ...
        //The rest of my position update code
    }
}

很明显,我是Java游戏编程的初学者,我可能没有最好的编码实践,所以你能提供的任何其他建议都会很棒。但是,我的主要问题是,由于某种原因,我的角色有时会拒绝接受键盘输入。有人可以帮忙吗?

1 个答案:

答案 0 :(得分:1)

您可能需要使成员upPressed为volatile,以便在线程之间正确共享。尝试将volatile关键字添加到upPressed的定义中。

e.g。

public volatile upPressed = false;
  

使用volatile变量可降低内存一致性的风险   错误,因为对volatile变量的任何写入都会建立一个   在与之后的相关读取之前发生   变量。这意味着始终对volatile变量进行更改   其他线程可见。