1

Android用の1v1バトルを使用してターンベースのゲームを作成しようとしています。私の基本的なゲーム ループは、2 人のファイターが死んでいるかどうかをチェックし、そうでない場合は次に誰が行くかをチェックします。プレイヤーの番の場合は、攻撃ボタンがクリックされるのを待つ必要があります。コンピューターの番である場合、ランダムな攻撃を実行します。プログラムがユーザー入力を待機するのに問題があります。ここでボタンリスナーを設定しようとしましたが、うまくいきません。[編集] どのキャラクターが移動するかの決定は、回復整数に基づいています。各攻撃には回復値 (50 ~ 100) があり、キャラクターの回復に追加されます。nextMove() メソッドはどちらが 0 に近いかをチェックし、両方の文字から差を引きます。これにより、ゲームはより多くの戦略を必要とすることができます。

その時点でゲームを一時停止するにはどうすればよいですか

これがコードです

public void battle(){
    boolean playerGo;
    while(!checkDead()){
        playerGo=nextMove();  //returns true if its the players turn to go
        if(playerGo){
            //The game should wait here for the user input

            moveButton1.setOnClickListener(this);

        }
        else{
            randomMove();  //game automatically goes
        }
    }

}
4

2 に答える 2

3

アプリの起動時に、イベント ハンドラーを含むすべてが実行される 1 つのスレッドがあります。セットアップを行って Battle() を呼び出した後、そのスレッドはそこに座ってループを回っています。ループをぐるぐる回るのに忙しくて、処理待ちのクリック イベントがあることに気付かないのです。

いくつかのオプションがあります:

  1. コードを再構築します。プレイヤーが動いてゲームが動くというのが基本的な構造のようです。このループを完全に削除して、代わりrandomMove()にプレイヤーの動きを処理するたびに呼び出すことができます。OnClickListenerforでプレーヤーの動きを処理しmoveButton1ます。そうすれば、すべてがイベントで発生します。これは全体的により単純であり、おそらく正しいことです。
  2. コードを機能させるには、可能な限り最小限の変更を加えてください。これはおそらく、 while ループの内容を にプルすることを意味しRunnable、 を呼び出してスケジュールしますHandler.post。最初の行はcheckDeadtrue の場合に呼び出して返します。最後の行は を再スケジュールしRunnableます。その間に while ループの本体があります。これの効果は、ループ本体が実行され、次にイベント ハンドラーがターンを取得し、次にループ本体が実行され、次にイベント ハンドラーが実行されるということです。これはおそらく悪い考えです。
  3. 別のスレッドで Battle() を実行します。これはおそらく悪い考えです。

なぜ 2. と 3. は悪い考えなのですか? モバイル デバイスでは、バッテリーの寿命は貴重です。何かを何度も実行する必要があるかどうかを確認するためのチェックを実行すると、CPU がバッテリーの寿命を食いつぶすために忙しくなります。何かをする必要があるまで何もせずにそこに座っている方がはるかに良いです - これがオプション 1 で達成されることです。

では、2. と 3. が悪いアイデアである場合、なぜそれらについて言及するのでしょうか? まあ、2.あなたが実際に尋ねた質問に対する答えに最も近いものだからです。3. について言及したのは、現在のコードがゲーム ロジックのかなり明確な具現化であるという意味があるからです。別のスレッドで実行されるように作り直すことができ、nextMove() が true を返す代わりに、nextMove() はプレーヤーが移動するまで待機します (これにはセマフォ、ミューテックス、またはプロミスが含まれます)。しかし、これは明示的にマルチスレッド化されたプログラムになるため、正しく記述するのは困難です。プログラミングのキャリアのこの段階では、それを試みないことをお勧めします。最も可能性の高い結果は、プログラムが停止して永遠に待機するか、診断が非常に困難な方法でデータ構造を破壊することです。

于 2012-08-09T17:02:29.513 に答える
1

Button.SetOnClickListener() 関数は、ユーザーがボタンをクリックしたときにのみトリガーされます。そのため、ユーザー入力まで待機\ブロックしません。これは Android の設計によるものであり、ユーザー入力を待機するブロッキング ウィンドウを持つことはできません。代わりに、デザインを変更して、「ユーザーが移動しました」というヒントを表示します。

  1. ユーザーはボタンをクリックして最初に移動します。
  2. SetOnclickListener() が呼び出されます。その中にユーザーアクションコードを入れます。
  3. SetOnclickListener() の終わりに向かって、コンピューター アクション コードがあります。

このサイクルを使用すると、ユーザーの移動とコンピューターの移動を連鎖させることができます。

于 2012-08-09T16:56:43.957 に答える