游戏循环完全冻结了我的程序

Posted

技术标签:

【中文标题】游戏循环完全冻结了我的程序【英文标题】:Game loop completely freezes my program 【发布时间】:2014-06-21 14:09:50 【问题描述】:

原始问题

我目前正在开发一个显示地图的简单应用程序,稍后将实现单位的​​寻路逻辑。到目前为止,我已经实现了地图和视图,并且在我实现游戏循环之前一切都运行良好。

启用游戏循环后,程序会冻结。即使游戏循环执行得很好,我也无法再关闭窗口并且地图没有显示。我过去曾两次使用过这个游戏循环,直到现在都没有遇到任何问题。

编辑:游戏循环继续正常执行,而其他一切都冻结了。

这里涉及到两个函数:

public GameController() 
    paused = true;

    frame = new GameFrame(this);

    map = new Map(500, 500);
    mvm = new MapViewModel(map.getMap(), map.getWidth(), map.getHeight());

    //TODO: gameLoop() currently breaks the game.

    gameLoop();


public void gameLoop() 
    double tickTime, lastTick;

    for (;;) 
        tickTime = System.nanoTime();
        lastTick = tickTime;

        //Repaints the frame
        update();

        while (tickTime - lastTick < NANOSECONDS_PER_UPDATE) 
            try 
                Thread.sleep(1);
             catch (InterruptedException ignored) 

            tickTime = System.nanoTime();
        
    

edit2:我正在使用 Swing。实际的绘制发生在我的 GamePanel (JPanel) 的 paintComponent 方法中:

@Override
public void paintComponent(Graphics g) 
    Graphics2D g2 = (Graphics2D) g;

    //Paints the map
    painter.paintMap(g2, controller.getMvm());

显然,如果您有任何其他问题,请随时提出。提前致谢。

解决方案

这是我现在使用的代码,GameController 和更新没有改变。

public void gameLoop() 
    timer = new Timer(MILLISECONDS_PER_UPDATE, updater);
    timer.start();

updater 是我作为私有变量添加到类的 ActionListener。

private ActionListener updater = new ActionListener() 
    @Override
    public void actionPerformed(ActionEvent e) 
        System.out.println("test2");
        update();
    
;

您可以在本地添加更新程序,但我更喜欢这种方式。

【问题讨论】:

update() 是做什么的? 哦,对不起。目前它只重绘游戏框架。奇怪的是,程序在冻结其他所有内容的同时继续正常执行游戏循环。 感谢您的更新。 Swing 标记已添加到您的问题中。 【参考方案1】:

您没有告诉我们您可能正在使用什么 GUI 库,但假设它可能是 Swing,看起来您正在 Swing 事件线程上运行一些长时间运行的代码,主线程负责执行所有 Swing图形并用于与用户交互。如果是这样,那么代码将阻止 Swing 重绘 GUI,从而冻结您的应用程序。

我的建议是:

不要这样做。不要在主事件线程上运行任何长时间运行的代码。 请考虑使用Swing Timer 来执行您的“游戏循环”。 或者,如果您必须使用 while 循环和线程睡眠,请在事件线程之外执行此操作,但要确保所有改变 Swing 对象状态的 Swing 调用都在事件时完成线程。 有关 Swing 线程的更多信息,请阅读Concurrency in Swing。

【讨论】:

是的,我正在使用 Swing。我已将信息添加到问题中。我将研究 Swing Timer,但能否详细说明线程选项或将我链接到一个好的资源?我从未使用过多个线程。 @Marv:我自己,我会使用 Swing Timer,因为它更容易实现,并且我在上面的答案中包含了教程的链接,但如果你绝对需要使用单独的后台线程,请阅读我添加到答案中的其他链接。 再次感谢。使用 Swing Timers 效果很好。如果可以的话,我将编辑我的问题以包含我的最终代码以供将来参考。 @Marv:是的,只要您将其添加到末尾并且不删除原始问题的基本部分就可以了。

以上是关于游戏循环完全冻结了我的程序的主要内容,如果未能解决你的问题,请参考以下文章

线程不起作用,它冻结我的应用程序[重复]

线程睡眠冻结了我的代码。 Java 客户端-服务器通信

ABPeoplePickerNavigationController 冻结我的应用程序

为啥我的冻结应用程序被检测为可能的病毒?

释放 CCScheduler 时,啥可能导致我的程序冻结?

如何在我的 iOS 应用程序中调试冻结问题