
目前我們的主戰(zhàn)坦克已經(jīng)能夠開(kāi)炮擊毀敵人坦克了,但敵人坦克不會(huì)開(kāi)炮貌似比較欺負(fù)人。今天我們讓敵人坦克也擁有開(kāi)炮功能。同時(shí),我們要為游戲設(shè)定關(guān)卡,讓它變得好玩起來(lái)。
讓敵人坦克開(kāi)炮
在EnemyTank類中,添加Shoot函數(shù)幾乎和MainTank中完全相同,代碼如下:
void EnemyTank::Shoot(list<Object*>& lstBullets)
{
Bullet* pBullet = new Bullet(m_pos, m_dir, m_color);
lstBullets.push_back(pBullet);
m_bNeedShoot = false;
}
這里唯一的區(qū)別是最后一句話,我們對(duì)m_bNeedShoot屬性進(jìn)行了賦值。
敵人坦克和主戰(zhàn)坦克最大的區(qū)別在于自動(dòng)開(kāi)炮,它不像主戰(zhàn)坦克那樣通過(guò)相應(yīng)空格鍵執(zhí)行開(kāi)炮函數(shù),它是通過(guò)一定的算法完成自主開(kāi)炮。因此我們?cè)趍ain函數(shù)中通過(guò)判斷m_bNeedShoot屬性來(lái)執(zhí)行Shoot函數(shù)。
在Move函數(shù)中,我們添加下面這段代碼:
if (m_stepCnt % MAX_STEP_SHOOT == 0)
{
m_bNeedShoot = true;
}
這段代碼有點(diǎn)類似于敵人坦克的自動(dòng)轉(zhuǎn)向功能,我們讓它每移動(dòng)MAX_STEP_SHOOT步就通過(guò)將m_bNeedShoot設(shè)為true來(lái)執(zhí)行開(kāi)炮功能。
最后,我們?cè)趍ain函數(shù)中繪制坦克時(shí)加入下面這段代碼:
if ((*it)->NeedShoot())
{
EnemyTank* p = (EnemyTank*)*it;
p->Shoot(lstBullets);
}
當(dāng)判斷NeedShoot()返回值為true時(shí),調(diào)用Shoot()函數(shù)進(jìn)行開(kāi)炮。
關(guān)卡設(shè)置
我們?cè)谕嬗螒驎r(shí),有一些必要的參數(shù)非常重要。比如,主要人物的生命值,等級(jí),敵人數(shù),分?jǐn)?shù)等等。下面我們就給坦克大戰(zhàn)中添加這些元素,讓它變得更有游戲的樂(lè)趣。
我們?yōu)楣こ烫砑右唤M新的文件Setting.h和Setting.cpp,代碼如下:
Setting.h
#ifndef __SETTING_H__
#define __SETTING_H__
#include <list>
using namespace std;
class Setting
{
public:
static void NewGameLevel();
static void TankDamaged();
static int GetLife()
{
return m_nLife;
}
static int GetGameLevel()
{
return m_nGameLevel;
}
static int GetTankLevel()
{
return m_nTankLevel;
}
static int GetTankNum()
{
return m_nTankNum;
}
static int GetSumScore()
{
return m_nSumScore;
}
static int GetTankSum()
{
return m_nTankSum;
}
static bool m_bNewLevel;
private:
static int m_nLife; // 生命值
static int m_nGameLevel; // 當(dāng)前游戲關(guān)卡
static int m_nTankLevel; // 當(dāng)前坦克級(jí)別
static int m_nTankNum; // 當(dāng)前坦克數(shù)
static int m_nSumScore; // 總分
static int m_nTankScore; // 擊毀坦克得分
static int m_nTankSum; // 共擊毀坦克數(shù)
};
#endif
在Setting類中,我們添加了一組static屬性。同時(shí),添加了訪問(wèn)這些參數(shù)的static接口。這里重點(diǎn)關(guān)注兩個(gè)函數(shù):
NewGameLevel()函數(shù),在每一關(guān)開(kāi)始時(shí)初始化每一關(guān)的屬性信息。TankDamaged()函數(shù),在每次擊毀一個(gè)坦克時(shí)調(diào)用,完成相關(guān)屬性的數(shù)據(jù)更新。具體如下:
Setting.cpp
include "Setting.h"
bool Setting::m_bNewLevel = true;
int Setting::m_nLife = 3;
int Setting::m_nGameLevel = 0;
int Setting::m_nTankLevel = 1;
int Setting::m_nTankNum = 5;
int Setting::m_nSumScore = 0;
int Setting::m_nTankScore = 5;
int Setting::m_nTankSum = 0;
void Setting::NewGameLevel()
{
m_nGameLevel++;
m_nTankNum = 10 + 5 * (m_nGameLevel - 1);
m_nTankScore += 5;
}
void Setting::TankDamaged()
{
m_nTankNum--;
m_nSumScore += m_nTankScore;
m_nTankLevel = m_nSumScore / 150 + 1;
m_nTankSum++;
if (m_nTankNum == 0)
{
m_bNewLevel = true;
}
}
前一部分是static屬性的初始化,后面是兩個(gè)函數(shù)的實(shí)現(xiàn)。相信大家一看就懂。這里的具體規(guī)則大家可以自行修改,制定規(guī)則才是游戲開(kāi)發(fā)中最有樂(lè)趣的一部分。
繪制成績(jī)
相關(guān)的數(shù)據(jù)我們需要繪制在屏幕的右半部分。我們?cè)贕raphic類中添加一個(gè)static函數(shù):
static void ShowScore();
實(shí)現(xiàn)如下:
const int SCORE_LEFT = 810;
const int SCORE_TOP = 5;
void Graphic::ShowScore()
{
COLORREF fill_color_save = getfillcolor();
COLORREF color_save = getcolor();
//setfillcolor(m_color);
//setcolor(m_color);
rectangle(SCORE_LEFT, SCORE_TOP, SCORE_LEFT + 200, SCORE_TOP + 40);
RECT r = { SCORE_LEFT, SCORE_TOP, SCORE_LEFT + 200, SCORE_TOP + 40 };
wsprintf((LPWSTR)m_pArray, _T("第 %d 關(guān)"), Setting::GetGameLevel());
drawtext((LPWSTR)m_pArray, &r, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
r.top += 50;
r.bottom += 50;
wsprintf((LPWSTR)m_pArray, _T("分 數(shù) : %d"), Setting::GetSumScore());
drawtext((LPWSTR)m_pArray, &r, DT_VCENTER | DT_SINGLELINE);
r.top += 50;
r.bottom += 50;
wsprintf((LPWSTR)m_pArray, _T("級(jí) 別 : %d"), Setting::GetTankLevel());
drawtext((LPWSTR)m_pArray, &r, DT_VCENTER | DT_SINGLELINE);
r.top += 50;
r.bottom += 50;
wsprintf((LPWSTR)m_pArray, _T("生 命 : %d"), Setting::GetLife());
drawtext((LPWSTR)m_pArray, &r, DT_VCENTER | DT_SINGLELINE);
r.top += 50;
r.bottom += 50;
wsprintf((LPWSTR)m_pArray, _T("敵人數(shù) : %d"), Setting::GetTankNum());
drawtext((LPWSTR)m_pArray, &r, DT_VCENTER | DT_SINGLELINE);
r.top += 50;
r.bottom += 50;
line(SCORE_LEFT, r.bottom, SCREEN_WIDTH - 5, r.bottom);
r.top += 50;
r.bottom += 50;
wsprintf((LPWSTR)m_pArray, _T("共擊毀敵人數(shù) : %d"), Setting::GetTankSum());
drawtext((LPWSTR)m_pArray, &r, DT_VCENTER | DT_SINGLELINE);
setcolor(color_save);
setfillcolor(fill_color_save);
}
最后,需要把這些調(diào)用放在main函數(shù)中,這里不做說(shuō)明,請(qǐng)大家自己試一下。如果自己寫不出來(lái)請(qǐng)?jiān)谖业?a target="_blank" rel="nofollow">GitHub中下載完整代碼。
執(zhí)行效果就是文章開(kāi)頭的圖片效果。
我是天花板,讓我們一起在軟件開(kāi)發(fā)中自我迭代。
如有任何問(wèn)題,歡迎與我聯(lián)系。
上一篇:C++代碼訓(xùn)練營(yíng) | 坦克大戰(zhàn)(6)
下一篇:C++代碼訓(xùn)練營(yíng) | 坦克大戰(zhàn)(8)