13.游戏的最后实现以及计时

HJ Lv2

13.游戏的最后实现以及计时

速度的控制

我们在前面说过,若是想实现动画效果必须使用while(1)循环(以下简称为主循环)绘制整个画布。但是这样循环过快,会使得植物的摇摆动画和僵尸动画速度过快。如果我们使用在每次循环后使用Sleep()函数设置延时,那么会使得鼠标键盘消息也会有延迟。并且在之前的代码中,豌豆发射函数toshoot()的检测逻辑是遍历每个植物,若是当前植物是豌豆射手并且当前行有僵尸则发射豌豆。这样会使得发射速率过快。
为了解决以上问题,我们设想可以通过某些办法实现主循环中不同事件有不同的速度。例如

1
2
3
4
5
6
7
8
9
10
11
int FrameControl = 0;//控制speed  
while (1) {
if (FrameControl % 100 == 0) {
//这里放置延时100的事件
}
if (FrameControl % 2000 == 0) {
//这里放置延时2000的事件
} ......
FrameControl = (FrameControl == 100001) ? 1 : FrameControl + 1;
//防止控制帧率的变量过大溢出
}

这里在循环外先声明变量FrameControl,然后每次循环该变量加1。用于控制事件的触发频率。它来控制不同事件的执行时间。
每次循环迭代结束时,FrameControl 的值都会增加 1。当 FrameControl 达到 100001 时,它会被重置为1,而不是继续增加。这样做是为了防止 FrameControl 的值变得过大而导致整数溢出。通过这种方式,FrameControl 的值始终保持在 1 到 100000 的范围内。

游戏输赢的检测

在前面我们介绍了函数checkGameStatus();
具体可以点击这里查看
这个函数返回一个值用来判断游戏胜利与否。我们需要在每次主循环中判断游戏状态,如果游戏输或者赢则跳出循环。

游戏倒计时功能的实现

上面我们说过可以使用变量FrameControl来控制各种事件的速度,那么我们是否可以利用这个来实现倒计时功能呢?
我们不知道一次循环的事件是多少,我们可以近似取2000次循环为一秒,即每2000循环时间减1。
例如:

1
2
3
if (FrameControl % 2000 == 0) {
stime--;
}

下面给出游戏的主体代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
void gameStart() {
BeginBatchDraw();
int gamestatus = -1;//先设置游戏状态为-1
int FrameControl = 0;//控制帧率
while (1) {//以下顺序不可更改
clickMsg();
if (FrameControl % 100 == 0) {//放慢植物摇摆和僵尸前进帧率
//在这里绘制背景,植物,僵尸,豌豆,改变僵尸状态,检测僵尸吃植物
}
if (FrameControl % 2000 == 0) {
//在这里写豌豆发射,时间减1
gamestatus = checkGameStatus();
if (...) {//判断游戏结束条件
break;
}
}
//检测豌豆击中僵尸,释放豌豆链表
FlushBatchDraw();
FrameControl = (FrameControl == 100001) ? 1 : FrameControl + 1;//防止控制帧率的变量过大溢出
}
EndBatchDraw();
if (gamestatus == 1) {
//如果胜利
}
if (gamestatus == 2) {
//如果失败
}
}

在主循环后判断游戏输赢,并绘制相应提示。延迟1秒后退出游戏。