10

ブラックジャックゲームを作ったのですが、AIプレイヤーにカードをとるまでの間に一時停止してもらいたいです。Thread.sleep(x)を使用してみましたが、AIプレーヤーがすべてのカードの取得を完了するまでフリーズします。Swingはスレッドセーフではないことを知っているので、タイマーを調べましたが、これにどのように使用できるか理解できませんでした。これが私の現在のコードです:

while (JB.total < 21) {

          try {
            Thread.sleep(1000);
          } catch (InterruptedException ex) {
            System.out.println("Oh noes!");
          }

          switch (getJBTable(JB.total, JB.aces > 0)) {
            case 0:
              JB.hit();
              break;
            case 1:
              break done;
            case 2:
              JB.hit();
              JB.bet *= 2;
              break done;
          }
        }

ところで、hit(); メソッドはGUIを更新します。

4

4 に答える 4

7

タイマーを見ましたが、どうやって使うのかわかりませんでした

あなたが言うようにあなたがEDTで行われるべきGUIを更新しているので、タイマーは解決策です。

あなたの懸念が何であるかわかりません。カードを配り、タイマーを開始します。タイマーが発動したとき、あなたは別のカードを取るか、ホールドすることにします。あなたがあなたの停止を保持するとき、タイマー。

于 2011-08-31T03:19:57.573 に答える
4

さて、タイマーについての簡単な説明。

まず、クラスにjava.util.Timer変数が必要であり、プロジェクトにはjava.util.TimerTask(Taskerと呼びましょう)から拡張された別のクラスが必要です。

Timer変数の初期化はとても簡単です。

Timer timer = new Timer();

今タスカークラス:

public class Tasker extends TimerTask {
    @Override
    public void run() {
        actionToDo(); // For example take cards 
    }

    // More functions if they are needed
}

最後に、関連するタスカーを使用したタイマーのインストール:

long delay = 0L;
long period = pauseTime;
timer.schedule(new Tasker(),delay,period);

スケジュール関数は次のことを示します。Fisrtparam:各期間ミリ秒で実行するアクション(TimerTaskクラスまたはその拡張のrun関数を実行します)2番目のparam:タイマーを開始する必要があるとき。この場合、スケジュール関数が呼び出されたときに開始されます。次の例は、schedule関数を呼び出してから1秒後に開始することを示していますtimer.schedule(new Tasker(),1000,period); 。3番目のパラメーター:Tasker.run()関数の1回の呼び出しと次の呼び出しの間のミリ秒。

このマイクロチュートリアルをご理解いただければ幸いです:)。何か問題があれば、もっと詳しい情報を聞いてください!

敬具!

于 2011-08-31T07:58:22.813 に答える
4

次のコードは、JTextAreaとJButtonを持つJFrameを示しています。ボタンがクリックされると、タイマーはイベントを繰り返し(ボタンの間に2番目の遅延を入れて)、現在の時刻を行に追加するボタンに関連するactionListenerに送信します。

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Calendar;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JTextArea;
import javax.swing.Timer;


public class TimerTest extends JFrame implements ActionListener{

    private static final long serialVersionUID = 7416567620110237028L;
    JTextArea area;
    Timer timer;
    int count; // Counts the number of sendings done by the timer
    boolean running; // Indicates if the timer is started (true) or stopped (false)

    public TimerTest() {
        super("Test");
        setBounds(30,30,500,500);
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        setLayout(null);

        area = new JTextArea();
        area.setBounds(0, 0, 500, 400);
        add(area);

        JButton button = new JButton("Click Me!");
        button.addActionListener(this);
        button.setBounds(200, 400, 100, 40);
        add(button);

        // Initialization of the timer. 1 second delay and this class as ActionListener
        timer = new Timer(1000, this);
        timer.setRepeats(true); // Send events until someone stops it
        count = 0; // in the beginning, 0 events sended by timer
        running = false;
        System.out.println(timer.isRepeats());
        setVisible(true); // Shows the frame
    }

    public void actionPerformed(ActionEvent e) {
        if (! running) {
            timer.start();
            running = true;
        }
        // Writing the current time and increasing the cont times
        area.append(Calendar.getInstance().getTime().toString()+"\n");
        count++;
        if (count == 10) {
            timer.stop();
            count = 0;
            running = false;
        }
    }

    public static void main(String[] args) {
        // Executing the frame with its Timer
        new TimerTest();
    }
}

このコードは、javax.swig.Timerオブジェクトの使用方法のサンプルです。質問の特定のケースに関連して。タイマーを停止するifステートメントは変更する必要があり、明らかに、actionPerformedのアクションを変更する必要があります。次のフラグメントは、ソリューションactionPerformedのスケルトンです。

public void actionPerformed(ActionEvent e) {
    if (e.getComponent() == myDealerComponent()) {
    // I do this if statement because the actionPerformed can treat more components
        if (! running) {
            timer.start();
            runnig = true;
        }
        // Hit a card if it must be hitted
        switch (getJBTable(JB.total, JB.aces > 0)) {
          case 0:
              JB.hit();
              break;
          case 1:
              break done;
          case 2:
              JB.hit();
              JB.bet *= 2;
              break done;
        }
        if (JB.total >= 21) { // In this case we don't need count the number of times, only check the JB.total 21 reached
            timer.stop()
            running = false;
        }

    }
}

私見これは問題を解決します、今@user920769はactionListenerと開始/停止条件をどこに置くかを考えなければなりません...

@kleopatra:このタイマークラスの存在を見せてくれてありがとう、私はそれについて何も知りません、そしてそれは素晴らしいです、swingアプリケーションに多くのタスクを可能にします:)

于 2011-08-31T14:50:55.723 に答える
3

このチュートリアルでは、スレッドを処理せずに、目的を達成するためにタイマーを使用する方法が明確になっていると思います。

于 2011-08-31T04:52:10.290 に答える