我正在制作像蛇一样的游戏。我的“开始”按钮有问题。当我开始一切运行良好但是如果我再次用按钮开始游戏,一条新的蛇正在移动得更快,并且每次使用按钮重新启动时它会比最后一条移动得更快。我不知道代码有什么问题,有人可以解释我的错误吗?
// In Frame class
addButton(buttonPanel, "Start", event ->
{
counter = -1; // resets points counting
area.start(); // area is a JPanel variable in Frame class
area.snake();
});
// In JPanel class
public void start()
{
body.removeAll(body); // ArrayList with snake body elements
add();
body.get(0).setX(300);
body.get(0).setY(300);
repaint();
}
public void snake()
{
Runnable r = () ->
{
try {
while(!isCollided())
{
for(int a=body.size()-1; a>0 ;a--) // Moving elements
{
if(a>0)
{
body.get(a).setX(body.get(a-1).getX());
body.get(a).setY(body.get(a-1).getY());
}
}
body.get(0).move();
double a = Math.abs(((body.get(0).getCenterX())-(food.getRandX()+5)));
double b = Math.abs(((body.get(0).getCenterY())-(food.getRandY()+5)));
if((a<10) && (b<10)) // Eating and growing a snake
{
food.newFood();
add();
}
this.repaint();
Thread.sleep(waiting); // waiting is final int = 100;
}
if(isCollided()) return;
}
catch (InterruptedException e) { return;}
};
Thread t = new Thread(r);
t.start();
}
答案 0 :(得分:0)
在每个snake()
调用中,您可以创建一个移动蛇的新线程。我不知道他们被处置的地方。
解决这个问题的方法之一就是只拥有一个&#39; Thread
。按下按钮,您可以重置该字段(包括蛇)。
这里的技巧是确保你的数据结构(代表蛇和字段)不会被两个线程同时修改(就像你有一个移动线程和一个UI线程处理那个按钮点击重置该字段)。
同步可以用来克服这个困难。
private final Object monitor = new Object();
然后在您的移动线程中
while (!isCollided()) {
synchronized (monitor) {
// make all the modifications to the shared data (i.e. the field)
}
...
Thread.sleep(...);
}
在你的新游戏中#&#39;按钮单击处理程序:
synchronized (monitor) {
// reset the shared data (the field)
}
重要的是要确保synchronized
下的代码能够快速运行。如果您的移动线程获取锁定然后在其中工作几秒钟,那么您的按钮单击处理程序将必须等待所有这些秒,并且您的UI将冻结。