2017-06-14 10 views
1

私はJavaを使ってゲームを作っており、ユーザーがメニュー画面で「再生」を押すとゲーム画面で3からカウントダウンするためにタイマーを使いたいと思っています。私のタイマーはJavaで正しくカウントされません

ここに私のコードです:

int seconds = 3; 

private void countdown(Graphics g) { 

    Timer timer = new Timer(); 

    TimerTask task = new TimerTask() { 
     public void run() { 
      if(seconds >= 0) { 
       System.out.println(seconds); 
       seconds--; 
      } 
      if(seconds == -1) { 

       timer.cancel(); 
      } 
     } 
    }; 

    timer.schedule(task, 1000, 1000); 
} 

私はここに私のゲームのdrawメソッドでカウントダウンを使用します。

public void draw(Graphics g) { 

    //background 
    g.setColor(Color.BLACK); 
    g.fillRect(0, 0, WIDTH, HEIGHT); 

    //count 
    countdown(g); 
} 

私はこれを変更しますが番号を印刷するには、コンソールを使用しています後でdrawString()を使用して、カウントダウンを画面に描画します。

私のメニュー画面で「再生」を押すと、ゲーム画面に1秒間の一時停止があり、番号がすべてコンソールに表示されます。問題は、数字の印刷の間に2番目の遅延がないことです。それらはすべて同時に印刷されます。どんな助け?

+0

作品罰金

はたとえば、あなたのスイングタイマーは、そののactionPerformedメソッド次のようになりますActionListenerを使用することができます。 [mcve]を投稿してください。 – shmosel

+0

ドローメソッドを使用しましたが、秒は1秒間隔で減少しましたか? –

+0

私は 'countdown()'メソッドをやっただけで、1秒間隔で0にカウントダウンしました。 'draw()'メソッドが質問にどのように関係しているのか分かりません。 – shmosel

答えて

1

drawが繰り返し呼び出された場合は、複数のタイマーが作成されるため、各タイマーからプリントアウトが取得されます。これにより、秒カウントも減少します。

各カウントダウン機能で作成するのではなく、1つのタイマーを作成し、カウントダウン機能で秒の値を設定することもできます。

+0

これを修正すると、繰り返し呼び出されることはありませんが、まだタイマーが画面に表示されます。 –

+0

これはどういう意味ですか? 'プライベートint秒= 3; \tプライベートタイマータイマー=新しいタイマー(); \t \tます。private voidカウントダウン(グラフィックスグラム){ \t \t \t \t TimerTaskをタスク=新しいTimerTaskを(){ \t \t \tます。public void実行(){ \t \t \t \t場合(秒> = 0){ \t \t \t \t \t System.out.println(秒); \t \t \t \t \t秒 - ; \t \t \t \t} \t \t \t \t IF(秒== -1){ \t \t \t \t \t timer.cancel()。 \t \t \t \t} \t \t \t} \t \t}。 \t \t \t \t timer.schedule(task、1000、1000); \t} ' –

+0

私はお詫びします、私は最後のものをフォーマットする方法を知らなかった。 –

0

あなたが作成および/またはタイマー

をキャンセルしているあなたの seconds変数をリセットする必要がありますあなたのプログラムは、スイングやAWTのGUIプログラムであることを、そしてもしそうなら、あなたは間違った型を使用している表示されます
 Timer timer = new Timer(); 
     seconds = 3; //Reset here 
     .......... 
     .......... 

     if(seconds == -1) { 
      timer.cancel(); 
      seconds = 3; // Reset here 
     } 
+0

私がそれをすると、カウントダウンが3から0まで非常に高速に繰り返され、停止しません。 –

+0

これは、複数のタスクを作成したことを意味します。これは意図したものですか? – Zakir

+0

私は最初に_drawString()_を使ってカウントダウンショーを行うことを意図していましたが、私はタイマーを3から0に数えたいと思っていました。 –

1

ここではjava.util.Timerjava.util.TimerTaskの両方のSwingスレッドセーフではありません。これは、あなたのGUIがフリーズすることがあります、あなたが見ているように、数字は表示されません。代わりに、これらのGUI用に特別に作成されたタイマー、Swing Timer (click on this link for the tutorialを使用してください。また、あなたがやっているはずのものとまったく逆の描画コードからタイマーを呼び出しています。代わりに、タイマーはカウント変数の状態を変更してからrepaint()に電話する必要があります。描画コードは、カウント変数の値を取得し、GUI内に表示します。

public void actionPerformed(ActionEvent e) { 
    if (counter != 0) { 
     // if the counter hasn't reached the end 
     counter--; // reduce counter by one 
     repaint(); // tell the GUI to repaint 
    } else { 
     timer.stop(); // otherwise at the end, so stop the timer 
     countDownAction.setEnabled(true); // and re-enable the button 
    } 
} 

完全なGUIの例は次のようになります:私にとって

import java.awt.Dimension; 
import java.awt.Font; 
import java.awt.Graphics; 
import java.awt.Graphics2D; 
import java.awt.RenderingHints; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import javax.swing.*; 

@SuppressWarnings("serial") 
public class CountDown extends JPanel { 
    public static final int TIMER_DLEAY = 1000; 
    private static final Font COUNTER_FONT = new Font(Font.SANS_SERIF, Font.BOLD, 400); 
    private static final int TEXT_X = 200; 
    private static final int TEXT_Y = 500; 
    private int counter; 
    private JSpinner spinner = new JSpinner(new SpinnerNumberModel(5, 0, 20, 1)); 
    private CountDownAction countDownAction = new CountDownAction("Count Down"); 
    private JButton countDownButton = new JButton(countDownAction); 
    private Timer timer; 

    public CountDown() { 
     setPreferredSize(new Dimension(800, 600)); 
     add(new JLabel("Starting Value:")); 
     add(spinner); 
     add(countDownButton); 
    } 

    @Override 
    protected void paintComponent(Graphics g) { 
     super.paintComponent(g); 
     Graphics2D g2 = (Graphics2D) g; 
     g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, 
       RenderingHints.VALUE_TEXT_ANTIALIAS_ON); 
     g.setFont(COUNTER_FONT); 
     String text = String.format("%02d", counter); 
     g.drawString(text, TEXT_X, TEXT_Y); 
    } 

    private class CountDownAction extends AbstractAction { 
     public CountDownAction(String name) { 
      super(name); 
      int mnemonic = (int) name.charAt(0); 
      putValue(MNEMONIC_KEY, mnemonic); 
     } 

     @Override 
     public void actionPerformed(ActionEvent e) { 
      // inactivate the button/action 
      countDownAction.setEnabled(false); 
      counter = (int) spinner.getValue(); 
      repaint(); 
      timer = new Timer(TIMER_DLEAY, new TimerListener()); 
      timer.start(); 
     } 
    } 

    private class TimerListener implements ActionListener { 
     @Override 
     public void actionPerformed(ActionEvent e) { 
      if (counter != 0) { 
       // if the counter hasn't reached the end 
       counter--; // reduce counter by one 
       repaint(); // tell the GUI to repaint 
      } else { 
       timer.stop(); // otherwise at the end, so stop the timer 
       countDownAction.setEnabled(true); // and re-enable the button 
      } 
     } 
    } 

    private static void createAndShowGui() { 
     JFrame frame = new JFrame("CountDown"); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.getContentPane().add(new CountDown()); 
     frame.pack(); 
     frame.setLocationRelativeTo(null); 
     frame.setVisible(true); 
    } 

    public static void main(String[] args) { 
     SwingUtilities.invokeLater(() -> createAndShowGui()); 
    } 
} 
関連する問題