Как получить ожидаемый порядок действий в моем игровом цикле? - PullRequest
0 голосов
/ 18 марта 2019

Я не совсем понимаю, что происходит за кулисами, и, следовательно, что я могу сделать, чтобы правильно кодировать эту проблему.Я ищу объяснение, которое приведет меня к самому себе.Это просто забавный домашний проект (я не студент), где я пишу пошаговое приложение.Тем не менее, сцены сражений рассчитаны случайным образом, а не поочередно, поэтому мое желание таково:

  1. Отображение начального значения битвы на экране в течение 2 секунд
  2. Расчет первой схватки
  3. Текущий обновленный счет битвы на экране в течение 2 секунд
  4. Вычисление 2-й перестрелки
  5. ...
  6. ...
  7. Настоящая победа илиПоражение на экране

Проблема, с которой я столкнулся, заключается в том, что в настоящее время приложение работает следующим образом:

  1. Текущий начальный счет битвы на экране
  2. Рассчитатьвсе стычки
  3. Страница отображает ноль для номера, так как он, по-видимому, уже возвращен?

Код выглядит так:

void fightBattle(){
    setContentView(R.layout.brigands);
    boolean winnerDetermined = false;
    while(!winnerDetermined) {
        boolean brigandsWon = brigandsWon(player, brigandCount);
        if(brigandsWon) {
            player.removeWarriors(2);
        }
        displayWarriors(player);
        if(brigandsWon){
            if(player.getWarriors() < 2){
                winnerDetermined = true;
            }
        }
        if(!brigandsWon) {
            brigandCount = brigandCount / 2;
        }
        displayBrigands();
        if(brigandCount == 0){
            winnerDetermined = true;
        }
    }
}

private void displayWarriors(Player player){
    final Player currentPlayer = player;
    new CountDownTimer(2000, 2000) {
        public void onTick(long millisUntilFinished) { }
        public void onFinish() {
            setContentView(R.layout.warriors);
            TextView warrior_count_tv = findViewById(R.id.warrior_count_tv);
            warrior_count_tv.setText(currentPlayer.getWarriors());
        }
    }.start();
}

private void displayBrigands(Player player){
    new CountDownTimer(2000, 2000) {
        public void onTick(long millisUntilFinished) { }
        public void onFinish() {
            setContentView(R.layout.brigands);
            TextView brigand_count_tv = findViewById(R.id.brigand_count_tv);
            brigand_count_tv.setText(Integer.toString(brigandCount));
        }
    }.start();
}

В конечном итоге, что я хочусм. что-то вроде приведенного ниже sudo-кода:

displayPage1For2Seconds;
while(somethingIsTrue){
    calculateNumber;
    displayPage2For2Seconds;
    displayPage3for2Seconds;
}
displayPage4For2Seconds;

1 Ответ

0 голосов
/ 18 марта 2019

Рассчитать все стычки

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

введите цикл while -> вызвать displayWarriors () -> создать CountDownTimer (), чтобы сделать что-то через 2 секунды -> вернуться к циклу while -> вызвать displayBrigands () -> создать CountDownTimer() чтобы сделать что-то через 2 секунды -> вернуться к циклу while -> делать то же самое, пока вы не выйдете, пока

С этим кодом вы получите кучу CountDownTimers, которые создаются и выполняются одновременно(почти) раз, поэтому через две секунды все они пытаются установить представление на какое-то значение (с неопределенным поведением, как вы упомянули, что это происходит).

Есть несколько способов сделать то, что вы хотите.Вы можете использовать поток, например:

void fightBattle(){
    setContentView(R.layout.brigands);
    new Thread(new Runnable() {
         public void run() {
             // I assume R.layout.brigands is the initial screen that you want to show for 2 seconds?!? In this case wait 2 seconds
             TimeUnit.Seconds.sleep(2);    
                 boolean winnerDetermined = false;
    while(!winnerDetermined) {
        // ...  
        // from your code it seems you want to show this for 2 seconds?
        displayWarriors(player);
        TimeUnit.Seconds.sleep(2);     
        //...
        displayBrigands();
        // also show this for 2 seconds
        TimeUnit.Seconds.sleep(2);    
        // ... 
    }
         }
    }).start();
}

Тогда ваши методы отображения будут выглядеть примерно так:

private void displayWarriors(Player player){
    // you need to wrap this code in a runOnUiThread() method(from the activity)
    // because we are on a background thread and we are changing views!
    final Player currentPlayer = player;
    setContentView(R.layout.warriors);
    TextView warrior_count_tv = findViewById(R.id.warrior_count_tv);
    warrior_count_tv.setText(currentPlayer.getWarriors()); 
}

Другой подход заключается в использовании обработчика и разбиении вашего кода в Runnables.что вы тогда планируете в подходящее время.

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