繁体   English   中英

UI在调试模式下按预期更新,但在正常运行时不执行任何操作

[英]UI updates as expected in debug mode, but does nothing when run normally

我正在NetBeans中创建一个基于简单回合的游戏。 GUI初始化后,它将调用函数herosTurn(),等待用户选择并从单独的类Hero创建该选择的结果。 当我在“调试”模式下单步执行代码时,会得到正确的结果,但是如果我只运行代码,则除非在文本输入区等待输入的过程中不断添加等待函数,否则不会将任何内容附加到文本区域。 我见过其他与此类似的问题,但它们都涉及多线程,但我不认为这是我正在做的事情。 任何帮助将不胜感激。

这是主要的类:

package Flow;

import Forms.Battleinterface;


/**
 *
 * @author Steemo
 */
public class battle { 
    public static int hAct;
    public static int gLife = 200;

    public static void herosTurn() {
        hAct = 0;

        Forms.Battleinterface.biText.append("What will you do?");
        while (hAct == 0){
            // adding the line below makes code work but is ugly.
            //Forms.Battleinterface.biText.append(".");
            continue;
        }
        if (hAct == 1){
            Entities.Hero.attack();
        }
    }

    public static void main(String args[]) {
        Battleinterface battleinterface = new Forms.Battleinterface();
        Battleinterface.Start();
        while (gLife > 0) {
            herosTurn();
        }


    }
}

这是Hero()类,位于单独的程序包中:

package Entities;

import java.util.Random;

/**
 *
 * @author Steemo
 */
public class Hero {
    static Random hGen = new Random(54154454);

    public static void attack() {
        int hAtt = 0;
        hAtt = hGen.nextInt(6) + 15;
        Forms.Battleinterface.biText.append("\nYou swing your axe and do " + hAtt
                + " Damage!!!");
    }

}

我没有附加用于生成GUI(Battleinterface)的类,因为GUI可以正常运行,唯一发生的另一件事就是输入hAct的传递。 如果需要,我可以附加它。

替换此代码...

while (hAct == 0){
  continue;
}

...与此相反:

while (hAct == 0){
  try {
    Thread.yield();
  } catch (InterruptedException interruptedEx) {
    // Log the interruption somewhere.
  }
}

假设您正在某种程度上使用AWT / Swing? 这是一个无限循环,阻止其他线程运行。 通过这样做,您永远不会让UI线程实际进行任何更新,这意味着它似乎挂起。 您可能不需要自己执行任何线程处理,但是AWT / Swing内置了执行各种功能的线程,它们需要定期获取CPU时间来完成工作。

之所以能在调试中工作,是因为调试器在您逐步调试它时暂停了herosTurn方法,从而允许UI线程进行其更新(包括从用户处获取输入),但是在简单地运行游戏时, herosTurn方法永远不会暂停,并且该方法占用了应用程序可用CPU时间的100%。

最后,正如Mike Clark所提到的,通常不应该使用无限循环编写UI。 相反,您可以定义触发事件的组件。 这些事件将通知您的代码,并做出适当的反应。 这就是所谓的UI事件模型。 如果您使用的是Swing, 则此处将介绍有关在事件模型中工作的介绍性信息。

由于UI编码,渲染性能的复杂性,以及与AWT / Swing并非是游戏的良好工具这一现实相关的其他原因,我通常也不会在游戏中使用AWT / Swing。 话虽如此,如果您愿意深入研究UI代码以完成游戏,那么基于回合的游戏就可以通过这种方式正常工作(因为渲染性能要求通常要低得多),在先前的答案中已经概述

嗯,将文本缓冲区刷新到文本区域可能存在问题。 尝试在每次打印后显式刷新文本缓冲区,以查看是否有区别。

在我看来,您的程序陷入了herosTurn()方法的while循环中,只要该函数未返回,如果将此游戏编程为单线程应用程序,则不会更新。

当您取消注释Forms.Battleinterface.biText.append(".");时,它会起作用Forms.Battleinterface.biText.append("."); 行cos,然后每次迭代将信号发送到GUI,从而导致其更新。

游戏通常具有一个主游戏循环,可从中控制程序的所有元素。 也许改变您的实施策略会有所帮助?

我不是游戏程序员,所以这可能不是最好的方法,但是为什么不尝试设置一个运行每100毫秒的javax.swing.Timer呢? 在计时器动作内部,您可以编写所有代码来检查和推进游戏状态并向用户生成输出。

我建议在JTextField中收集用户的输入,该JTextField与游戏输出的打印位置分开。 如果您想知道用户何时按Enter键发送他们键入的内容,可以在JTextField上注册一个ActionListener。

textField.addActionListener(yourListener);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM