2

「ミリオネアになりたい人」ゲームを書いていて、すべてをセットアップしましたが、タイマーの問題です。

ゲームは次のように機能します。ユーザーが質問に正解すると、次に進みます。そうでない場合、ゲームは終了し、再びプレイすることを選択できます。

ゲームが最初に実行されたときは問題なく、タイマーは本来の動作を行います。30 秒から開始してカウントダウンし、秒を表示します。

ただし、ユーザーが「もう一度再生」ボタンをクリックすると、前のタイマーが新しいタイマーで続行されます。このような:

-timerA には、ユーザーが負けるまでに 20 秒残っていました (a で示されます)。

-timerB は、次にゲームがプレイされるときに開始されます (b で示されます)。

出力: 20a 29b 19a 28b 18a 27b 17a 26b ....... 2a 11b 1a 10b 9b 8b 7b 6b 5b 4b 3b 2b 1b

ここに、CountDown というタイマー クラスがあります。

  import java.util.Timer;
  import java.util.TimerTask;

  public class CountDown {

      static Timer timer;
      public static int seconds = 30;

      public CountDown() {
          timer = new Timer();
          timer.schedule(new DisplayCountdown(), 0, 1000);
      }

      class DisplayCountdown extends TimerTask {

          int seconds = 30;

          public void run() {

                  if (seconds == 0) {
                      timer.cancel();
                      timer.purge();
                      return;
                  }

              if (seconds > 0) {
                  PlayFrame.timer.setText("" + seconds); //jLabel used to display seconds
                  seconds--;
                  if (seconds < 30) {
                      if (PlayFrame.right == true) { //check if question was answered correctly
                          System.out.print("true"); //testing purposes
                          PlayFrame.right = false;
                          PlayFrame.showQuestion();
                          PlayFrame.startTimer();
                          seconds = 0;
                          //break;
                      }
                      else if (PlayFrame.right == false) {
                          //break;
                      }
                  }      

                  else if (seconds == 0) { //if time runs out its automatic wrong answer
                      PlayFrame.wrong();
                      //break;
                  }      

                  else {
                      PlayFrame.wrong();
                      PlayFrame.timer.setText(null);
                      timer = new Timer();
                      //break;
                  }
              }
              System.out.println(seconds); // for testing purposes only
          }
      }
  }

ここに私のPlayFrameの一部があります:

  import java.awt.Color;
  import java.util.Timer;

  public class PlayFrame extends javax.swing.JFrame {

      public static void wrong() {
          //determines which losing frame to show
          if (count <= 2){
              LossLevel0 L0 = new LossLevel0();
              L0.setVisible(true);
          }
          else if (count > 2 && count <= 6 && count != 6){
              LossLevel1 L1 = new LossLevel1();
              L1.setVisible(true);
          }
          else {
              LossLevel1 L1 = new LossLevel1();
              L1.setVisible(true);
          }
          //"supposed" to stop the timer
          CountDown.timer.cancel();
          CountDown.timer.purge();
      }

      public static void startTimer() {
          //creates new CountDown object and timer, also resets seconds
          CountDown countdown = new CountDown();
          CountDown.timer = new Timer();
          CountDown.seconds = 30;
      }

ゲームを再起動すると問題が発生する可能性があると思います。そこにある唯一のコードは、すべての変数をゲーム開始前の元の状態にリセットすることです。そのようです:

    // Reset Everything
    PlayFrame.count = 0;
    PlayFrame.answer = new String();
    PlayFrame.count = 0;
    PlayFrame.right = false;
    PlayFrame.winnings = 0;
    CountDown.seconds = 30;
    CountDown.timer = new Timer();
    CountDown.timer.cancel();
    CountDown.timer.purge();

助けてください。さらに情報が必要な場合は、お尋ねください。

4

3 に答える 3

5

Swing アプリケーションでjava.util.Timerを使用しないでください。これらには、Swing イベント スレッドを尊重するため、javax.swing.Timerを使用する必要があります。したがって、あなたの質問は意味がありません。タイミングコードをすべて捨てて、適切なタイマーを試すことをお勧めします。ここでチュートリアルを見つけることができます: Swing Timer Tutorial

次に、コードで使用しているすべての静的メソッドとフィールドを削除し、インスタンス フィールドとメソッドに変更します。

JLabel に残り時間を表示する Swing Timer の例:

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.*;

public class TimerExample {

   private static void createAndShowGui() {
      Gui mainPanel = new Gui();

      JFrame frame = new JFrame("TimerExample");
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      frame.getContentPane().add(mainPanel);
      frame.pack();
      frame.setLocationByPlatform(true);
      frame.setVisible(true);
   }

   public static void main(String[] args) {
      SwingUtilities.invokeLater(new Runnable() {
         public void run() {
            createAndShowGui();
         }
      });
   }
}

class Gui extends JPanel {
   private static final long serialVersionUID = 1L;
   private static final String PRESS_BUTTON = "Press Button ";
   private static final String PRESS_BUTTON_AGAIN = "Press Button Again Within %02d Seconds!";
   private static final String YOU_LOSE = "You Lose!";
   private static final String YOU_WIN = "You Win!";
   private static final int PREF_W = 250;
   private static final int PREF_H = 100;
   private static final int TOTAL_SECONDS = 20;
   private static final int ONE_SECOND = 1000;

   private int elapsedSeconds = 0;
   private JLabel timerLabel = new JLabel(PRESS_BUTTON);
   private JButton button = new JButton("Button");
   private Timer myTimer;

   public Gui() {
      JPanel btnPanel = new JPanel();
      btnPanel.add(button);

      setLayout(new BorderLayout());
      add(btnPanel, BorderLayout.CENTER);
      add(timerLabel, BorderLayout.SOUTH);

      button.addActionListener(new ActionListener() {

         @Override
         public void actionPerformed(ActionEvent arg0) {
            if (myTimer != null && myTimer.isRunning()) {
               myTimer.stop();
               myTimer = null;
               timerLabel.setText(YOU_WIN);               
            } else {
               elapsedSeconds = 0;
               myTimer = new Timer(ONE_SECOND, new TimerListener());
               myTimer.start();
               String text = String.format(PRESS_BUTTON_AGAIN, TOTAL_SECONDS); 
               timerLabel.setText(text);
            }
         }
      });
   }

   @Override
   public Dimension getPreferredSize() {
      return new Dimension(PREF_W, PREF_H);
   }

   private class TimerListener implements ActionListener {
      @Override
      public void actionPerformed(ActionEvent e) {
         elapsedSeconds++;

         if (elapsedSeconds == TOTAL_SECONDS) {
            myTimer.stop();
            timerLabel.setText(YOU_LOSE);
         } else {
            String text = String.format(PRESS_BUTTON_AGAIN, TOTAL_SECONDS - elapsedSeconds);
            timerLabel.setText(text );
         }
      }
   }
}
于 2013-01-18T01:55:34.663 に答える
1

私がお勧めするのは、Timer 宣言を JFrame に移動し、タイマーが必要になるたびに「DisplayCountdown」クラスの新しいインスタンスを作成し、「timer.schedule(new DisplayCountdown(), 0, 1000)」を移動することです。 ;" 他にライン。

タイマー オブジェクトを消去すると、完全にリセットされるため、新しいタイマー オブジェクトを作成する必要はなく、新しい TimerTask を追加するだけです。

于 2013-01-18T02:22:22.927 に答える
0

解決しました、リンクsage88に感謝します!http://albertattard.blogspot.com/2008/09/practical-example-of-swing-timer.html

また、スイングタイマーの詳細については(このトピックの今後の検索用)http://www.asjava.com/swing/java-timer-tutorial/

public static void startTimer() {
    listener = new ActionListener() {
        @Override
        public void actionPerformed(ActionEvent event) {
            System.out.print("action");
            timerLabel.setText("" + seconds);
            seconds--;
            System.out.println(seconds);
            if (seconds < 0){
                System.out.print("zero");
                wrong();
            }
        }
    };
    displayTimer = new Timer(1000, listener);
    displayTimer.setInitialDelay(1);
    displayTimer.start();

    if (right == true){
        System.out.print("true");
        displayTimer.stop();
        right = false;
        seconds = 30;
        displayTimer = new Timer(10000, listener);
        displayTimer.setDelay(10000);
        displayTimer.setInitialDelay(1);
        displayTimer.start();
    }
    else if (right == null){
        System.out.print("null");
        displayTimer.stop();
        seconds = 30;
        displayTimer = new Timer(10000, listener);
        displayTimer.setInitialDelay(1);
        displayTimer.setDelay(10000);
        displayTimer.start();
    }
}
于 2013-01-18T22:38:47.350 に答える