首页 > 解决方案 > 如何在我的游戏循环中获得预期的动作顺序?

问题描述

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

  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;

标签: androidandroid-thread

解决方案


计算所有小冲突

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

进入while循环->调用displayWarriors()->创建CountDownTimer()2秒后做某事->返回while循环->调用displayBrigands()->创建CountDownTimer()2秒后做某事->返回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 中破坏您的代码,然后在适当的时间安排这些代码。


推荐阅读