C++代碼訓(xùn)練營(yíng) | 坦克大戰(zhàn)(7)

目前我們的主戰(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)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容

  • 上一篇中,我們添加了可以自動(dòng)行駛的敵人坦克,今天我們給主戰(zhàn)坦克添加最核心的功能——開(kāi)炮。 第一次重構(gòu) 既然要開(kāi)炮,...
    天花板閱讀 4,147評(píng)論 1 13
  • 上一篇中我們給主戰(zhàn)坦克添加了發(fā)射炮彈的功能。不過(guò)有一個(gè)問(wèn)題,炮彈飛到戰(zhàn)場(chǎng)邊緣時(shí),自動(dòng)消失的感覺(jué)不太好。我們今天來(lái)給...
    天花板閱讀 3,539評(píng)論 4 9
  • 上一篇中我們已經(jīng)得到了一個(gè)比較完善的游戲,不過(guò)有人反饋說(shuō)目前的難度較大,第三關(guān)已經(jīng)很難通過(guò)了。今天我們來(lái)做點(diǎn)小的修...
    天花板閱讀 3,863評(píng)論 11 18
  • 現(xiàn)在我們的游戲已經(jīng)初具規(guī)模,但如果主戰(zhàn)坦克一直是無(wú)敵狀態(tài)那也很無(wú)趣。今天我們來(lái)讓敵人的炮火發(fā)揮作用。 主戰(zhàn)坦克被擊...
    天花板閱讀 2,750評(píng)論 1 8
  • 這一篇中,我們繼續(xù)繼續(xù)進(jìn)行我們的坦克大戰(zhàn)。 位置信息數(shù)據(jù)結(jié)構(gòu) 在游戲設(shè)計(jì)過(guò)程中,需要記錄大量的位置信息,如果僅僅使...
    天花板閱讀 7,535評(píng)論 14 25