有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

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

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

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

我的问题是,当我按下键盘上的一个按钮时,输入肯定会在画布侧进行(我已经用打印语句确认了这一点),但它并不总是通过角色,我只能假设,由于角色的位置更新在一个单独的线程中运行,因此出现了一个问题

这是我的相关代码:

//
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) 个答案

  1. # 1 楼答案

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

    例如

    public volatile upPressed = false;
    

    Using volatile variables reduces the risk of memory consistency errors, because any write to a volatile variable establishes a happens-before relationship with subsequent reads of that same variable. This means that changes to a volatile variable are always visible to other threads.