现在我们的游戏已经初具规模,但如果主战坦克一直是无敌状态那也很无趣。今天我们来让敌人的炮火发挥作用。
主战坦克被击中
当敌人的炮弹和主战坦克接触时,主战坦克生命值减一。我们预设的主战坦克共有三条命,被击中三次后游戏结束。
为主战坦克添加碰撞检测大家应该很熟悉,修改之前的CheckCrash()函数如下:
C++代码
- void CheckCrash()
- {
-
- for (list<Object*>::iterator it = lstMainTankBullets.begin(); it != lstMainTankBullets.end(); it++)
- {
- for (list<Tank*>::iterator itt = lstTanks.begin(); itt != lstTanks.end(); itt++)
- {
- if (Shape::CheckIntersect((*it)->GetSphere(), (*itt)->GetSphere()))
- {
- (*itt)->SetDisappear();
- (*it)->SetDisappear();
- }
- }
- }
-
-
- for (list<Object*>::iterator it = lstBullets.begin(); it != lstBullets.end(); it++)
- {
- if (Shape::CheckIntersect((*it)->GetSphere(), mainTank.GetSphere()))
- {
- Setting::Die();
-
- if (Setting::GetLife() > 0)
- {
- (*it)->SetDisappear();
- }
- else
- {
- mainTank.SetDisappear();
- }
- }
- }
- }
新加入的代码通过一个for循环把主战坦克的Sphere和每一个敌人坦克的炮弹的Sphere进行碰撞检测,如果相交就调用Setting::Die()函数使主战坦克的生命减一。当生命值为0时,通过SetDisappear()函数让主战坦克消失。这个逻辑和敌人坦克被击毁时相同。
生命值计算
在Setting类中添加Die函数如下:
C++代码
- static void Die()
- {
- m_nLife -= 1;
- }
每调用一次这个函数,主战坦克的生命值减1。
在这里修改了生命值属性后,绘制界面时会自动更新生命数值。
游戏结束界面
当游戏结束时,需要显示一个“GameOver”的界面。在Graphic类中添加函数如下:
C++代码
- void Graphic::ShowGameOver()
- {
- COLORREF fill_color_save = getfillcolor();
- COLORREF color_save = getcolor();
-
- rectangle(BATTLE_GROUND_X1 + 100, BATTLE_GROUND_Y1 + 200, BATTLE_GROUND_X1 + 700, BATTLE_GROUND_Y1 + 380);
-
- LOGFONT fontBak;
- gettextstyle(&fontBak);
-
- LOGFONT f = fontBak;
- f.lfHeight = 48;
- _tcscpy_s(f.lfFaceName, _T("黑体"));
- f.lfQuality = ANTIALIASED_QUALITY;
- settextstyle(&f);
- wsprintf((LPWSTR)m_pArray, _T("GAME OVER"));
- outtextxy(BATTLE_GROUND_X1 + 300, BATTLE_GROUND_Y1 + 250, (LPWSTR)m_pArray);
-
- f.lfHeight = 18;
- settextstyle(&f);
- wsprintf((LPWSTR)m_pArray, _T("按 Enter 键退出"));
- outtextxy(BATTLE_GROUND_X1 + 550, BATTLE_GROUND_Y1 + 350, (LPWSTR)m_pArray);
-
- settextstyle(&fontBak);
-
- setcolor(color_save);
- setfillcolor(fill_color_save);
- }
这个函数的实现和ShowGameLevel()函数非常类似。后期我们可以优化一下把它们的公用部分解耦出来。
程序流程控制
最后,我们把main()函数修改如下:
新加入一个bGameOver变量,用来表示游戏结束。
当循环中发现主战坦克消失时,打印出游戏结束界面,之后通过skip变量暂停程序流程,等待用户按下Enter键。
C++代码
- if (mainTank.IsDisappear())
- {
- skip = true;
- bGameOver = true;
-
- Graphic::ShowGameOver();
- continue;
- }
之后的下一次循环,程序通过判断bGameOver变量跳出循环,游戏结束。
好了现在来试试我们的成功吧,看你能够过几关。
今天的代码请在GitHub中下载。