处理多个玩家线程并重新绘制

时间:2016-06-10 21:39:09

标签: java multithreading thread-safety game-engine

我目前正在研究一个java轰炸机人游戏,游戏运行正常,但我确实有一个并发修改异常,反复抛出。
在我的游戏中,我有两个玩家,每个玩家都有自己的线程,使用计时器以60fps的速度运行(thread.run())。在每个玩家运行方法结束时,我尝试重新运行重新运行线程以及线程运行。

方法1:

public void loop() {
    if (!gameover) {
        player1_thread.run(); //run player 1 thread
        player2_thread.run(); //run player 2 thread
        gui.repaint() //repaint panel
    }
} 

方法2:

public class Player extends Character { //Character implements Runnable
...
    @Override
    public void run() {
        play();
        ...
        game.render();
    }
}

这两种方法都会按预期抛出并发修改,所以如何避免错误,只需执行以下操作:

player1.run(); //call the run method of each player class
player2.run();

为玩家1提供了优势。

修改

方法4:

import java.util.Timer

public class Player extends Character { //Character implements Runnable
    private Timer gameTimer

    @Ovveride
    public void run() {
        gameTimer.scheduleAtFixedRate(new TimerTask() {

            @Override
            public void run() {
                play();
                ...
                game.render();
            }

        }, 0, 1000/60);
    }
}

public class Game extends AbstractGame {

    private void init() {
        ...
        Thread player1_Thread = new Thread(player1);
        Thread player2_Thread = new Thread(player2);
        gui = new GameGraphics(this); //subclass of JPanel
        player1_thread.start();
        player2_thread.start();
    }

    /* this method is called at a constant 60fps(like the player timer) in the main game timer in my abstract game class */
    public void gameLoop(){
        if(!gameover){
            render();
        ...
        }
    }
}

这也会引发异常

2 个答案:

答案 0 :(得分:0)

错误:调用run()将使用主线程执行指令。

正确:调用player1.start()来启动一个新线程,以便在新启动的线程中执行run(){...}。

答案 1 :(得分:0)

如果PlayerThread的子类,则可以使用.start()启动它,但不要在循环中启动线程。你只需要启动一个线程,之后它将一直运行直到该类中的run方法完成,很可能你想用循环编写一个run方法,所以它一直运行到你停止它为止。如果你想只用一个线程来运行游戏,你可以实现Runnable,并做你现在做的事情,在一个循环中调用run()。那时只有一个主线程。

通过调用线程对象上的run,你没有启动一个线程,它只是在那个对象中调用run方法。

我认为最好的办法是,只需一个线程使用模型中的数据更新绘图。从播放器线程更改此模型中的数据。