我正在写一个“谁想成为一个百万人”游戏,我已经完成了所有设置,这只是计时器的一个问题。
游戏的工作方式如下:如果用户得到正确的问题,他/她会继续前进。如果没有,游戏就结束了,他们可以选择再玩一次。
当游戏第一次运行时,它很好并且计时器完成应有的操作 - 从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();
请帮助,如果您需要更多信息,请询问!
答案 0 :(得分:5)
您不应该将java.util.Timer与Swing应用程序一起使用。对于这些,您应该使用javax.swing.Timer,因为这将尊重Swing事件线程。因此,你的问题没有实际意义,我建议你抛出所有的时间码,并尝试正确的计时器。您可以在此处找到该教程: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 );
}
}
}
}
答案 1 :(得分:1)
我建议做的是将Timer声明移动到JFrame中,然后在每次需要计时器时创建“DisplayCountdown”类的新实例,并移动“timer.schedule(new DisplayCountdown(),0 ,1000);“在其他地方。
如果清除定时器对象,它将完全重置,因此您不需要创建新的定时器对象,只需添加一个新的TimerTask。
答案 2 :(得分: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();
}
}