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

戰(zhàn)場(chǎng)范圍

之前我們的坦克從戰(zhàn)場(chǎng)的一邊走出之后會(huì)從另一邊重新進(jìn)入戰(zhàn)場(chǎng)。這樣不符合我們游戲的定義。我們需要把它們改成遇到戰(zhàn)場(chǎng)邊就不能再繼續(xù)向前走了谴麦。

主戰(zhàn)坦克

修改MainTank.cpp中的Move方法蠢沿,如下:

void MainTank::Move()
{
    switch (m_dir)
    {
    case UP:
        m_pos.SetY(m_pos.GetY() - m_step);
        if (m_rectSphere.GetStartPoint().GetY() < Graphic::GetBattleGround().GetStartPoint().GetY())
            m_pos.SetY(m_pos.GetY() + m_step);
        break;
    case DOWN:
        m_pos.SetY(m_pos.GetY() + m_step);
        if (m_rectSphere.GetEndPoint().GetY() > Graphic::GetBattleGround().GetEndPoint().GetY())
            m_pos.SetY(m_pos.GetY() - m_step);
        break;
    case LEFT:
        m_pos.SetX(m_pos.GetX() - m_step);
        if (m_rectSphere.GetStartPoint().GetX() < Graphic::GetBattleGround().GetStartPoint().GetX())
            m_pos.SetX(m_pos.GetX() + m_step);
        break;
    case RIGHT:
        m_pos.SetX(m_pos.GetX() + m_step);
        if (m_rectSphere.GetEndPoint().GetX() > Graphic::GetBattleGround().GetEndPoint().GetX())
            m_pos.SetX(m_pos.GetX() - m_step);
        break;
    default:
        break;
    }

    CalculateSphere();
}

敵人坦克

敵人坦克也是一樣,Move方法完全相同匾效。修改EnemyTank.cpp中的Move方法舷蟀,如下:

void EnemyTank::Move()
{
    switch (m_dir)
    {
    case UP:
        m_pos.SetY(m_pos.GetY() - m_step);
        if (m_rectSphere.GetStartPoint().GetY() < Graphic::GetBattleGround().GetStartPoint().GetY())
            m_pos.SetY(m_pos.GetY() + m_step);
        break;
    case DOWN:
        m_pos.SetY(m_pos.GetY() + m_step);
        if (m_rectSphere.GetEndPoint().GetY() > Graphic::GetBattleGround().GetEndPoint().GetY())
            m_pos.SetY(m_pos.GetY() - m_step);
        break;
    case LEFT:
        m_pos.SetX(m_pos.GetX() - m_step);
        if (m_rectSphere.GetStartPoint().GetX() < Graphic::GetBattleGround().GetStartPoint().GetX())
            m_pos.SetX(m_pos.GetX() + m_step);
        break;
    case RIGHT:
        m_pos.SetX(m_pos.GetX() + m_step);
        if (m_rectSphere.GetEndPoint().GetX() > Graphic::GetBattleGround().GetEndPoint().GetX())
            m_pos.SetX(m_pos.GetX() - m_step);
        break;
    default:
        break;
    }

    CalculateSphere();
}

運(yùn)行一下程序,效果如下:

問(wèn)題大家肯定看到了面哼,坦克運(yùn)行到戰(zhàn)場(chǎng)邊就停止了野宜,這樣游戲沒(méi)法進(jìn)行下去了。我們要修改敵人的坦克精绎,讓它們自己會(huì)調(diào)整方向速缨。

自動(dòng)轉(zhuǎn)向的敵人坦克

敵人坦克的自動(dòng)轉(zhuǎn)向包括兩個(gè)部分:

  • 坦克遇到戰(zhàn)場(chǎng)邊后隨機(jī)調(diào)轉(zhuǎn)方向
  • 坦克每走10步隨機(jī)調(diào)轉(zhuǎn)方向

代碼如下:

EnemyTank.h

#ifndef __ENEMY_TANK__
#define __ENEMY_TANK__

#include "Tank.h"

#define MAX_STEP 10

class EnemyTank : public Tank
{
public:
    EnemyTank()
    {
        RandomTank();
    }

    ~EnemyTank(){}

    void Display();
    void Move();

protected:
    void CalculateSphere();
    void RandomTank();
    // 隨機(jī)產(chǎn)生坦克方向 type: 1, 新方向必須與之前方向不同 2, 任意一個(gè)新方向
    void RandomDir(int type);

    int m_stepCnt;
};

#endif

EnemyTank類中添加了一個(gè)m_stepCnt屬性锌妻,用來(lái)記錄坦克當(dāng)前行駛的步數(shù)代乃。又定義了一個(gè)MAX_STEP宏定義最大的行駛步數(shù)。

RandomDir()用來(lái)隨即地產(chǎn)生坦克方向仿粹,參數(shù)type為1時(shí)產(chǎn)生一個(gè)和當(dāng)前方向不同的新方向搁吓,參數(shù)type為0時(shí),產(chǎn)生任意一個(gè)新方向吭历。

EnemyTank.cpp

這個(gè)文件中只有三個(gè)函數(shù)有變化堕仔。

void EnemyTank::RandomTank()
{
    m_pos.SetX(rand() % Graphic::GetBattleGround().GetWidth());
    m_pos.SetY(rand() % Graphic::GetBattleGround().GetHeight());
    m_color = WHITE;
    m_dir = (Dir)(Dir::UP + (rand() % 4));
    m_step = 2;
    m_stepCnt = rand() % MAX_STEP;
}

這個(gè)函數(shù)在初始化變量的時(shí)候?yàn)閙_stepCnt隨機(jī)產(chǎn)生一個(gè)當(dāng)前步數(shù)。為什么要在這里用隨即數(shù)呢晌区?如果每個(gè)坦克的當(dāng)前步數(shù)相同的話摩骨,那么到第十歩的時(shí)候所有的坦克會(huì)集體轉(zhuǎn)向,這樣會(huì)很奇怪朗若。不信大家可以試試恼五。

void EnemyTank::RandomDir(int type)
{
    if (type == 1)
    {
        Dir dir;
        while ((dir = (Dir)(Dir::UP + (rand() % 4))) == m_dir)
        {
            // Do nothing
        }

        m_dir = dir;
    }
    else
    {
        m_dir = (Dir)(Dir::UP + (rand() % 4));
    }
}

這個(gè)函數(shù)的功能剛才已經(jīng)介紹過(guò)了,實(shí)現(xiàn)方式也很簡(jiǎn)單哭懈。

void EnemyTank::Move()
{
    switch (m_dir)
    {
    case UP:
        m_pos.SetY(m_pos.GetY() - m_step);
        if (m_rectSphere.GetStartPoint().GetY() < Graphic::GetBattleGround().GetStartPoint().GetY())
        {
            m_pos.SetY(m_pos.GetY() + m_step);
            this->RandomDir(1);
        }
        break;
    case DOWN:
        m_pos.SetY(m_pos.GetY() + m_step);
        if (m_rectSphere.GetEndPoint().GetY() > Graphic::GetBattleGround().GetEndPoint().GetY())
        {
            m_pos.SetY(m_pos.GetY() - m_step);
            this->RandomDir(1);
        }
        break;
    case LEFT:
        m_pos.SetX(m_pos.GetX() - m_step);
        if (m_rectSphere.GetStartPoint().GetX() < Graphic::GetBattleGround().GetStartPoint().GetX())
        {
            m_pos.SetX(m_pos.GetX() + m_step);
            this->RandomDir(1);
        }
        break;
    case RIGHT:
        m_pos.SetX(m_pos.GetX() + m_step);
        if (m_rectSphere.GetEndPoint().GetX() > Graphic::GetBattleGround().GetEndPoint().GetX())
        {
            m_pos.SetX(m_pos.GetX() - m_step);
            this->RandomDir(1);
        }
        break;
    default:
        break;
    }

    CalculateSphere();

    m_stepCnt++;
    if (m_stepCnt >= MAX_STEP)
    {
        m_stepCnt = 0;
        this->RandomDir(0);
    }
}

Move()函數(shù)中灾馒,一旦遇到戰(zhàn)場(chǎng)邊就調(diào)用RandomDir()函數(shù)隨機(jī)出一個(gè)新的方向。每次移動(dòng)都用m_stepCnt屬性計(jì)步一次遣总,每走10歩就做一次隨機(jī)改變方向睬罗。

下面就是執(zhí)行效果:

這篇文章的相關(guān)代碼已經(jīng)上傳至GitHub

我是天花板,讓我們一起在軟件開(kāi)發(fā)中自我迭代旭斥。
如有任何問(wèn)題容达,歡迎與我聯(lián)系。


上一篇:C++代碼訓(xùn)練營(yíng) | 坦克大戰(zhàn)(2)
下一篇:C++代碼訓(xùn)練營(yíng) | 坦克大戰(zhàn)(4)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末垂券,一起剝皮案震驚了整個(gè)濱河市董饰,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖卒暂,帶你破解...
    沈念sama閱讀 211,817評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件啄栓,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡也祠,警方通過(guò)查閱死者的電腦和手機(jī)昙楚,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,329評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)诈嘿,“玉大人堪旧,你說(shuō)我怎么就攤上這事〗毖牵” “怎么了淳梦?”我有些...
    開(kāi)封第一講書(shū)人閱讀 157,354評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)昔字。 經(jīng)常有香客問(wèn)我爆袍,道長(zhǎng),這世上最難降的妖魔是什么作郭? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,498評(píng)論 1 284
  • 正文 為了忘掉前任陨囊,我火速辦了婚禮,結(jié)果婚禮上夹攒,老公的妹妹穿的比我還像新娘蜘醋。我一直安慰自己,他們只是感情好咏尝,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,600評(píng)論 6 386
  • 文/花漫 我一把揭開(kāi)白布压语。 她就那樣靜靜地躺著,像睡著了一般编检。 火紅的嫁衣襯著肌膚如雪胎食。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 49,829評(píng)論 1 290
  • 那天蒙谓,我揣著相機(jī)與錄音斥季,去河邊找鬼。 笑死累驮,一個(gè)胖子當(dāng)著我的面吹牛酣倾,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播谤专,決...
    沈念sama閱讀 38,979評(píng)論 3 408
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼躁锡,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了置侍?” 一聲冷哼從身側(cè)響起映之,我...
    開(kāi)封第一講書(shū)人閱讀 37,722評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤拦焚,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后杠输,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體赎败,經(jīng)...
    沈念sama閱讀 44,189評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,519評(píng)論 2 327
  • 正文 我和宋清朗相戀三年蠢甲,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了僵刮。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,654評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡鹦牛,死狀恐怖搞糕,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情曼追,我是刑警寧澤窍仰,帶...
    沈念sama閱讀 34,329評(píng)論 4 330
  • 正文 年R本政府宣布篮愉,位于F島的核電站阱飘,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏逐抑。R本人自食惡果不足惜膏燕,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,940評(píng)論 3 313
  • 文/蒙蒙 一钥屈、第九天 我趴在偏房一處隱蔽的房頂上張望悟民。 院中可真熱鬧坝辫,春花似錦、人聲如沸射亏。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,762評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)智润。三九已至及舍,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間窟绷,已是汗流浹背锯玛。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,993評(píng)論 1 266
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留兼蜈,地道東北人攘残。 一個(gè)月前我還...
    沈念sama閱讀 46,382評(píng)論 2 360
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像为狸,于是被迫代替她去往敵國(guó)和親歼郭。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,543評(píng)論 2 349

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

  • 這一篇中辐棒,我們繼續(xù)繼續(xù)進(jìn)行我們的坦克大戰(zhàn)病曾。 位置信息數(shù)據(jù)結(jié)構(gòu) 在游戲設(shè)計(jì)過(guò)程中牍蜂,需要記錄大量的位置信息,如果僅僅使...
    天花板閱讀 7,480評(píng)論 14 25
  • 目前我們的主戰(zhàn)坦克已經(jīng)能夠開(kāi)炮擊毀敵人坦克了泰涂,但敵人坦克不會(huì)開(kāi)炮貌似比較欺負(fù)人鲫竞。今天我們讓敵人坦克也擁有開(kāi)炮功能。...
    天花板閱讀 5,118評(píng)論 8 6
  • 上一篇中逼蒙,我們添加了可以自動(dòng)行駛的敵人坦克贡茅,今天我們給主戰(zhàn)坦克添加最核心的功能——開(kāi)炮。 第一次重構(gòu) 既然要開(kāi)炮其做,...
    天花板閱讀 4,075評(píng)論 1 13
  • 終于等到今天了顶考。在《21天C語(yǔ)言代碼訓(xùn)練營(yíng)》中,我就想講這個(gè)項(xiàng)目了妖泄,只是用C語(yǔ)言寫(xiě)會(huì)比較麻煩驹沿,我怕自己水平有限講不...
    天花板閱讀 12,584評(píng)論 7 62
  • 上一篇中我們給主戰(zhàn)坦克添加了發(fā)射炮彈的功能。不過(guò)有一個(gè)問(wèn)題蹈胡,炮彈飛到戰(zhàn)場(chǎng)邊緣時(shí)渊季,自動(dòng)消失的感覺(jué)不太好。我們今天來(lái)給...
    天花板閱讀 3,476評(píng)論 4 9