我用Java制作游戏,而repaint()
方法却以一种非常奇怪的方式行为不端。基本上,我需要在进行人工智能移动之前重新绘制电路板。这是我的方法,我称之为:
public void mouseClicked(MouseEvent e) {
mouseX = e.getX();
mouseY = e.getY();
int button = e.getButton();
if (button == MouseEvent.BUTTON1 || button == MouseEvent.BUTTON3) {
int mouseR = (mouseY / SIZE);
int mouseC = (mouseX / SIZE);
if (mouseR >= 0 && mouseC >= 0 &&
mouseR < board.length && mouseC < board[0].length) {
if (board[mouseR][mouseC] == 3) {
makeMove(mouseR, mouseC, playerColor);
getValidMoves((playerColor % 2) + 1);
repaint();
getAIMove();
}
}
}
repaint();
}
getAIMove()
的设计是为了让它在移动前等待几秒钟,因此玩家可以在看到AI之前看到移动的结果。不幸的是,虽然我在repaint()
之前拨打getAIMove()
,但更多的情况是:玩家点击他们想要移动的位置。几秒钟内似乎没有任何事情发生,然后玩家移动的结果和AI的移动显示在屏幕上。发生了什么事?
答案 0 :(得分:2)
option
事件处理程序中的所有代码都将在特殊的AWT / Swing Thread上运行。
mouseClicked()
不会立即重新绘制GUI - 它计划重新绘制,(请参阅this article),它也将在Swing线程上运行 - 但直到您的事件处理程序已经完成 - Swing线程一次只能做一件事!
所以直到事后你才会看到repaint()
的结果。
您可能需要在单独的后台线程中运行getAIMove()
逻辑,然后更新GUI(必须使用SwingUtilities.invokeLater()
或getAIMove()
帮助程序类在Swing线程中完成。)
或者,您可以使用SwingWorker
安排AI在Swing线程上运行 - 然后它将在第一个invokeLater()
之后运行。但是,这种方法是不可取的(除非AI非常快),因为在Swing线程再次释放以处理重新绘制之前,GUI将无响应。
另请参阅有关这些主题的Java教程:
答案 1 :(得分:0)
一位朋友和我想出了一个小技巧来击败@DNA描述的队列 - 这是我的新代码:
public void mousePressed( MouseEvent e )
{
mouseX = e.getX();
mouseY = e.getY();
int button = e.getButton();
if(button == MouseEvent.BUTTON1 || button == MouseEvent.BUTTON3)
{
int mouseR = (mouseY/SIZE);
int mouseC = (mouseX/SIZE);
if(mouseR >=0 && mouseC >= 0 && mouseR < board.length && mouseC < board[0].length)
{
if (board[mouseR][mouseC] == 3){
makeMove(mouseR, mouseC, playerColor);
}
}
}
repaint();
}
public void mouseReleased( MouseEvent e )
{
int button = e.getButton();
if(button == MouseEvent.BUTTON1 || button == MouseEvent.BUTTON3)
{
int mouseR = (mouseY/SIZE);
int mouseC = (mouseX/SIZE);
if(mouseR >=0 && mouseC >= 0 && mouseR < board.length && mouseC < board[0].length)
{
if (board[mouseR][mouseC] == playerColor){
getValidMoves((playerColor % 2) + 1);
getAIMove();
getValidMoves(playerColor);
}
}
}
repaint();
}
通过在按下鼠标时进行玩家移动,并等待AI移动直到释放鼠标,程序可以完成Swing线程并重新绘制板。感谢您的所有帮助!