蛇的线程

时间:2017-03-27 19:03:01

标签: java multithreading swing

我正在制作像蛇一样的游戏。我的“开始”按钮有问题。当我开始一切运行良好但是如果我再次用按钮开始游戏,一条新的蛇正在移动得更快,并且每次使用按钮重新启动时它会比最后一条移动得更快。我不知道代码有什么问题,有人可以解释我的错误吗?

// 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();
}

1 个答案:

答案 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将冻结。