戰(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)