如何在我的游戏循环中获得预期的动作顺序?

How to obtain the expected order of actions in my game loop?

我不完全了解幕后发生的事情,因此,我可以做些什么来正确编码这个问题。我正在寻找一个可以让我自己弄清楚的解释。这只是一个有趣的家庭项目(我不是学生),我正在编写一个回合制应用程序。但是,战斗场景是随机计算的持续时间,而不是回合制,所以我的愿望如下:

  1. 在屏幕上显示初始战斗计数 2 秒
  2. 计算第一次遭遇战
  3. 在屏幕上显示更新的战斗计数 2 秒
  4. 计算第二次冲突
  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;

Calculate all skirmishes

您当前的代码这样做是因为 while 循环实际上并没有停止等待。流程将是这样的:

进入 while 循环 -> 调用 displayWarriors() -> 创建 CountDownTimer() 以在 2 秒后执行某些操作 -> return 进入 while 循环 -> 调用 displayBrigands() -> 创建 CountDownTimer() 以执行操作2 秒后的东西 -> return 到 while 循环 -> 做同样的事情直到你退出 while

使用这段代码,您最终会得到一堆 CountDownTimer,它们在(几乎)相同的时间创建和执行,所以两秒后它们都会尝试将视图设置为某个值(具有不确定的行为,例如你提到它发生了)。

有多种方法可以满足您的需求。例如,您可以使用线程:

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()); 
}

另一种方法是使用 Handler 并在 Runnables 中中断代码,然后在适当的时间安排它。