我试图为我正在制作的教育游戏制作倒数计时器(仅用于学习目的),但我遇到了一些问题。
总结一下,我只需要一个计时器:
我的游戏有很多问题需要解决,每个问题必须在10秒之前解决。我创建了一个名为" Chronometer"为了解决我的游戏问题,但我不知道如何阻止它并抛出所需的异常(顺便说一句,这是联系我的观点的最佳方式? )。
目前它从10到0计数,但是停止,它会继续,下次从59计数到0 - 它永远不会停止。我该如何解决这个问题?
public class Chronometer {
private Timer chronometer;
private DateFormat format = new SimpleDateFormat("ss");
private Calendar calendar = Calendar.getInstance();
private final byte countType;
public static final byte PROGRESSIVE = 1;
public static final byte REGRESSIVE = -1;
public Chronometer(int years, int months, int days, int hours, int minutes, int seconds, byte countType) {
this.chronometer = new Timer();
calendar.set(years, months, days, hours, minutes, seconds);
this.countType = countType;
}
public void starts_chronometer(){
TimerTask task = new TimerTask() {
public void run() {
System.out.println(getTime());
}
};
chronometer.scheduleAtFixedRate(task, 0, 1000);
this.chronometer = null;
}
public int getTime() {
calendar.add(Calendar.SECOND, countType);
return Integer.parseInt(format.format(calendar.getTime()));
}
}
(失败,它会在计时器启动的同时抛出异常。)
public void starts_chronometer() throws Exception {
TimerTask task = new TimerTask() {
public void run() {
System.out.println(getTime());
}
};
chronometer.scheduleAtFixedRate(task, 0, 1000);
this.chronometer = null;
throw new Exception("The time's over!");
}
(失败,而不是9 ... 8 ... 7 ... 6它的工作方式类似9 ... 6 ... 5 ... 3 ... 1)
public void starts_chronometer() {
TimerTask task = new TimerTask() {
public void run() {
System.out.println(getTime());
if(getTime() == 0){
chronometer.cancel();
}
}
};
chronometer.scheduleAtFixedRate(task, 0, 1000);
this.chronometer = null;
}
我已经在StackOverflow中看到很多关于计时器的问题,但没有一个能帮我解决问题。
请帮我解决这个问题。
答案 0 :(得分:0)
这个问题的一个很好的解决方案是使用Observer模式。使用此模式,您可以使用Observers和Observables。观察者可以观察到Observables(因此得名)。 Obervable并不关心观察者是否在观察他。
我所提出的解决方案有两个类,Main类(Observer)和Chronometer类(Observable)。 Main类将自身添加为Chronometer对象的Observer,当Observerable有通知时,将运行方法void update(Observable, Object)
。计时器不再使用计时器了。相反,它使用一个将休眠10秒的线程,之后它将状态设置为已修改,并通知所有观察者,从而调用void update(Observable, Object)
。
通过这种实现,计时器将在完成后通知每个观察者。这将使您了解何时必须更新视图。
编辑:我已经更改了run
和update
方法的实现,因此每秒都会通知观察者。
主要课程:
public class Main implements Observer{
public static void main(String[] args) {
Main m = new Main();
Chronometer c = new Chronometer(2014, 7, 4, 13, 46, 21, (byte) 0);
c.addObserver(m);
c.run();
try {
Thread.sleep(200000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
@Override
public void update(Observable arg0, Object arg1) {
int time = (int)arg1;
if(time > 0){
System.out.println("Time left: " + time);
} else {
System.out.println("The time's over!");
//Update View
}
}
}
记时计:
public class Chronometer extends Observable implements Runnable{
private DateFormat format = new SimpleDateFormat("ss");
private Calendar calendar = Calendar.getInstance();
private final byte countType;
public static final byte PROGRESSIVE = 1;
public static final byte REGRESSIVE = -1;
public Chronometer(int years, int months, int days, int hours, int minutes, int seconds, byte countType) {
calendar.set(years, months, days, hours, minutes, seconds);
this.countType = countType;
}
public int getTime() {
calendar.add(Calendar.SECOND, countType);
return Integer.parseInt(format.format(calendar.getTime()));
}
@Override
public void run() {
int time = 10;
do {
try {
Thread.sleep(1000);
setChanged();
notifyObservers(time);
time--;
} catch (InterruptedException e) {
e.printStackTrace();
}
} while (time >= 0);
}
}
答案 1 :(得分:0)
尝试停止:
public class Chronometer {
private Calendar calendar = Calendar.getInstance();
private static final long TIME_0 = -62167489199561L;
private final byte countType;
public static final byte PROGRESSIVE = 1;
public static final byte REGRESSIVE = -1;
public Chronometer(int years, int months, int days, int hours, int minutes, int seconds, byte countType) {
calendar.set(years, months, days, hours, minutes, seconds);
this.countType = countType;
}
public void startChronometer(){
Timer t = new Timer();
TimerTask task = new TimerTask() {
public void run() {
System.out.println(getTime());
if(getTime()==0) throw new RuntimeException("Done");
calendar.add(Calendar.SECOND, countType);
}
};
t.scheduleAtFixedRate(task, 0, 1000);
}
//Returns seconds left
public long getTime() {
return Math.round((calendar.getTime().getTime()-TIME_0)/1000);
}
public static void main(String[] args) {
Chronometer c = new Chronometer(0, 0, 0, 0, 0, 10, REGRESSIVE);
c.startChronometer();
}
}