如何重新启动应用程序的更新循环

时间:2014-02-28 05:56:51

标签: java swing game-loop

我正在使用Java和Swing开发绘图应用程序。只要布尔变量设置为true,它就有一个不断运行的常量更新循环。循环位于线程内。

它工作正常,但现在我希望循环只在特定时间运行(仅在按下鼠标时),否则不运行。 (因此没有浪费记忆)。

要停止循环,我可以简单地将该变量设置为false。但我的问题是,如何在停止后重启循环?将该变量设置回true将不会重新启动循环。什么是一个好方法呢?

编辑:我的(一点简化)循环:

public void run(){

    int TICKS_PER_SECOND = 50;
    int SKIP_TICKS = 1000 / TICKS_PER_SECOND;
    int MAX_FRAMESKIP = 10;

    long next_game_tick = System.currentTimeMillis();
    int loops;

    boolean app_is_running = true;

    while( app_is_running ) {

        loops = 0;
        while( System.currentTimeMillis() > next_game_tick && loops < MAX_FRAMESKIP) {

            update();

            next_game_tick += SKIP_TICKS;
            loops++;
        }

        repaint();
    }

}

2 个答案:

答案 0 :(得分:0)

要在每FRAME_RATE ms执行一次线程主体,同时可由外部定义的布尔值控制,run方法可以这样构造:

public void run()
{
    long delay;
    long frameStart = System.currentTimeMillis();

    // INSERT YOUR INITIALIZATION CODE HERE

    try
    {
        while (true)
        {
            if (active)  // Boolean defined outside of thread
            {
                // INSERT YOUR LOOP CODE HERE
            }

            frameStart += FRAME_RATE;
            delay = frameStart - System.currentTimeMillis();
            if (delay > 0)
            {
                Thread.sleep(delay);
            }
        }
    }
    catch (InterruptedException exception) {}
}

此外,如果您想消除持续运行循环的轻微开销(对于大多数非活动线程),while循环中的布尔值可以替换为Semaphore对象:

while (true)
{
    semaphore.acquire();  // Semaphore defined outside thread with 1 permit

    // INSERT YOUR LOOP CODE HERE 

    semaphore.release();

    frameStart += FRAME_RATE;
    delay = frameStart - System.currentTimeMillis();
    if (delay > 0)
    {
        Thread.sleep(delay);
    }
}

要在外部停止循环,请使用semaphore.acquire();要重新启动它,请使用semaphore.release()

答案 1 :(得分:0)

使用Object.wait在线程未运行时挂起该线程。让另一个线程调用Object.notify将其从睡眠中唤醒。