十七、计时

一些游戏,也许是你正在开发的游戏,是基于时间的。这可能意味着游戏中的特定挑战有一个需要完成的时间限制,或者整个游戏本身只能玩预定的时间。

本章的解决方案将帮助你在游戏中创建一个计时器。然后,您将使用该计时器写入屏幕,并在到期后退出游戏操作。游戏中追踪时间的关键组件是 Android 类CountDownTimer()CountDownTimer()是一个非常强大但易于实现的工具。

17.1 比赛中的赛道时间

问题

用户应该只有固定的时间来完成任务。

解决办法

在你的游戏中使用一个CountDownTimer() 来追踪时间的长短。

它是如何工作的

建立计时器的关键是实例化一个CountDownTimer()CountDownTimer()类是 Android 的核心类,不依赖于 OpenGL ES。这意味着无论你的游戏使用的是 OpenGL ES 1、2 还是 3,你都可以在你的游戏中轻松使用CountDownTimer()。因此,本章中的示例与 OpenGL ES 版本无关。

第一步是实例化该类。

newCountDownTimer(millisecondsInFuture, countDownInterval) {
}

CountDownTime()的构造函数有两个参数。第一个参数millisecondsInFuture,是计时器的总持续时间,单位为毫秒。如果你想让计时器持续 30 秒,你可以将millisecondsInFuture设置为 30000。

new CountDownTimer(30000, countDownInterval) {
}

第二个参数countDownInterval指定何时触发间隔或tick。假设你想要执行一个动作,比如更新一个屏幕或者定期检查一个游戏任务的进度。您可以将countDownInterval设置为小于millisecondsInFuture的值,如下所示:

new CountDownTimer(30000, 1000) {
}

这段代码设置了一个新的CountDownTimer(),它将在 30 秒后到期,并每 1 秒触发一次tick。然而,在计时器完成之前,还有一些编码工作要做。你需要覆盖两个方法(见清单 17-1 )。

清单 17-1CountDownTimer()

new CountDownTimer(30000,1000) {
@Override
public void onTick(long millisUntilFinished) {

//perform any interval-based calls here
}

@Override
public void onFinish() {

//perform any clean up or ending of tasks here
};
}

第一个方法onTick(),在每个countDownInterval到期后调用。您需要覆盖的第二个方法是onFinish()。在CountDownTimer()完全到期后,调用onFinish()方法。

最后,使用start()方法启动定时器。从CountDownTimer()调用start()方法来激活计时器并开始倒计时(见清单 17-2 )。

清单 17-2start()

newCountDownTimer(30000,1000) {
@Override
public void onTick(long millisUntilFinished) {

}

@Override
public void onFinish() {

};
}.start();

方法的一个很好的用途是将时间写到屏幕上。例如,使用第 16 章中的解决方案,你可以用数字 0 到 9 建立一个精灵表。然而,它可以用来倒数时间,而不是记录分数(见清单 17-3 )。

清单 17-3 。显示时间

new CountDownTimer(30000,1000) {
@Override
public void onTick(long millisUntilFinished) {

switch(millisUntilFinished){
case(29000):
scoreTile.x = 0; //set the x and y to the location of the
scoreTile.y = 0; //correct sprite sheet image for the time digit
break;

...
}

}

@Override
public void onFinish() {

};
}.start();

17.2 当时间到期时停止动作

问题

当计时器到期时,游戏不会停止。

解决办法

当时间到时,使用CountDownTimer()onFinish()方法停止游戏。

它是如何工作的

要在时间到期时停止游戏,请使用onFinish()方法调用您的关闭例程。回头看看第四章中的食谱,你很可能有一个退出例程,可以从游戏菜单上的退出按钮调用。

当定时器到期时,你可以从onFinish()方法调用这个相同的例程(见清单 17-4 )。

清单 17-4 。游戏退出

new CountDownTimer(30000,1000) {
@Override
public void onTick(long millisUntilFinished) {

}

@Override
public void onFinish() {

gameView.exit(); //call the method that you established for exiting the game
};
}.start();

17.3 任务完成时停止定时器

问题

在玩家完成要求的任务后,游戏计时器继续运行。

解决办法

当玩家完成一个任务时,使用CountDownTimer()cancel()方法停止计时器。

它是如何工作的

您的游戏可能会被设置为要求玩家在给定的时间内完成一项任务或一系列任务。接下来的问题是,当任务完成时,如何停止计时器?

CountDownTimer包含一个cancel()方法,当您需要停止计时器时可以调用该方法。有效使用这个方法的关键是实例化一个CountDownTimer并限定它的范围,这样它就可以被游戏中的其他方法调用。清单 17-5 展示了如何实例化CountDownTimer(与配方 17.1 中的略有不同),然后使用cancel()停止计时器。

清单 17-5 。取消CountDownTimer

private CountDownTimer cdt;
...
cdt = new CountDownTimer(30000,1000) {
@Override
public void onTick(long millisUntilFinished) {

}

@Override
public void onFinish() {
//something bad happens to the player for failing
};
}.start();

... //rest of your game code

private checkTask(){
//this is a method that you create to check if the player
//has finished the required task
if(taskCompleted){
cdt.cancel();
}
}