Пользовательский интерфейс обновляется, как и ожидалось, в режиме отладки, но ничего не делает при нормальной работе - PullRequest
1 голос
/ 13 марта 2012

Я создаю простую пошаговую игру в 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.Если нужно, я могу прикрепить его.

Ответы [ 4 ]

1 голос
/ 13 марта 2012

Замените этот код ...

while (hAct == 0){
  continue;
}

... этим вместо этого:

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

Предполагается, что вы используете AWT / Swing на каком-то уровне?Это бесконечный цикл, предотвращающий запуск других потоков.Делая это, вы никогда не позволяете потоку пользовательского интерфейса фактически выполнять какие-либо обновления, что означает, что он кажется зависшим.Возможно, вы не выполняете какие-либо потоки самостоятельно, но AWT / Swing поставляется с потоками, встроенными для выполнения различных функций, и им необходимо периодически получать время ЦП для выполнения своей работы.

Причина, по которой это работает при отладкепотому что отладчик приостанавливает метод herosTurn, пока вы проходите по нему, позволяя потоку пользовательского интерфейса выполнять свои обновления (включая получение информации от пользователя), но при простом запуске игры метод herosTurn никогда не останавливаетсяи этот метод занимает 100% доступного процессорного времени для вашего приложения.

Наконец, как упоминает Майк Кларк , вы обычно не должны писать пользовательский интерфейс с бесконечными циклами.Вместо этого вы определяете компоненты, которые запускают события.Ваш код уведомляется об этих событиях и реагирует соответствующим образом.Это то, что известно как модель событий пользовательского интерфейса.Если вы используете Swing, вводная информация о работе в модели событий описана здесь .

Я бы также не стал использовать AWT / Swing для игр из-за сложностей, связанных сКодирование пользовательского интерфейса, производительность рендеринга и ряд других причин, связанных с реальностью того, что AWT / Swing не были созданы, чтобы быть хорошими инструментами для игр.При этом пошаговая игра может нормально работать таким образом (поскольку требования к производительности рендеринга часто намного ниже), если вы хотите углубиться в код пользовательского интерфейса, чтобы выполнить это, в дополнение к нескольким другим причинам, которые яизложил в предыдущий ответ .

0 голосов
/ 13 марта 2012

Я не программист игр, так что это может быть не лучшим подходом, но почему бы вам не попробовать настроить javax.swing.Timer, который запускается каждые, скажем, 100 миллисекунд. Внутри действия таймера вы можете написать весь код, который проверяет и улучшает состояние игры и генерирует вывод для пользователя.

Я бы предложил собрать пользовательский ввод в JTextField, отдельном от места, где выводится игровой вывод. Если вы хотите знать, когда пользователь нажимает клавишу ввода, чтобы отправить набранное, вы можете зарегистрировать ActionListener в JTextField.

textField.addActionListener(yourListener);
0 голосов
/ 13 марта 2012

Мне кажется, что ваша программа застряла в цикле while в методе herosTurn() Пока эта функция не вернулась, ничего не будет обновляться, если вы запрограммируете эту игру как однопоточное приложение.

Это работает, когда вы раскомментируете строку Forms.Battleinterface.biText.append(".");, потому что вы посылаете сигнал в GUI на каждой итерации, что приводит к его обновлению.

Игры обычно имеют основной игровой цикл, из которого контролируются все элементы программы. Может быть, изменение вашей стратегии реализации поможет?

0 голосов
/ 13 марта 2012

Хм, может быть проблема с очисткой вашего текстового буфера в текстовой области. Попробуйте явно очищать ваш текстовый буфер после каждой печати, чтобы увидеть, имеет ли это значение.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...