cocos2d-x遊戲開發系列教程-坦克大戰遊戲之敵方坦克AI的編寫

在上篇咱們完成了子彈和地圖碰撞的檢測,在這篇咱們將完成敵方坦克AI的編寫。數組

具體思路是屏幕中保持有四個敵方坦克,而後坦克隨機方向運動,而且子彈消失後1秒發射一次函數

1.咱們新建一個敵方坦克的AI類來控制地方坦克AI行爲:this

static const char* enemyTankType[] = 
{
	"normalU.png", "speedU.png", "armor1U.png"
};

class EnemyAI
{
public:
	EnemyAI();
	~EnemyAI();

	static EnemyAI* createEnemyAIWithTank(Tank* tank);
	void initEnemyAIWithTank(Tank* tank);
	void update(float delta);

private:
	void addTank(float delta);
	void tankAction(float delta);

private:
	CCArray* mEnemyTanks;
	Tank* mTank;
	TileMapInfo* mTileMapInfo;

	//出現地點
	CCPoint bornPoint[3];
};
上面目前只添加三種類型的敵方坦克,

在成員變量中,mEnemyTanks存放了全部的坦克,spa

mTank存放了玩家坦克,最後mTileMapInfo存放了地圖信息。.net

bornPoint存放了敵方坦克出身的三個位置。指針


2.先實現void EnemyAI::initEnemyAIWithTank(Tank* tank)來初始化咱們的EnemyAI類:code

void EnemyAI::initEnemyAIWithTank(Tank* tank)
{
	mTank = tank;
	mTileMapInfo = tank->getTileMapInfo();
	mEnemyTanks = CCArray::createWithCapacity(4);
	mEnemyTanks->retain();

	//初始化出現地點
	CCSize mapSize = mTileMapInfo->getTileMap()->getContentSize();
	CCSize tileSize = mTileMapInfo->getTileMap()->layerNamed("layer_0")->getMapTileSize();
	bornPoint[0] = ccp(tileSize.width, mapSize.height - tileSize.height);
	bornPoint[1] = ccp(mapSize.width / 2, mapSize.height - tileSize.height);
	bornPoint[2] = ccp(mapSize.width - tileSize.width, mapSize.height - tileSize.height);
}
在上面咱們初始化了敵方坦克出身的三個地點,而後建立了一個容量爲4的數組mEnemyTanks來存放敵方坦克對象。

3.再實現靜態方法返回EnmeyAI類指針:orm

EnemyAI* EnemyAI::createEnemyAIWithTank(Tank* tank)
{
	EnemyAI* enemyTank = new EnemyAI();
	enemyTank->initEnemyAIWithTank(tank);

	return enemyTank;
}

4.實現void EnemyAI::addTank(float delta):

其中delta是每一幀調用之間的事件間隔對象

void EnemyAI::addTank(float delta)
{
	static float deltaTimes = 0.0f;
	deltaTimes += delta;
	if (deltaTimes >= 2.0f)
	{
		deltaTimes = 0.0f;
		int count = mEnemyTanks->count();
		if (count < 3)	//先從固定位置添加三個坦克
		{
			Tank* enemyTank = Tank::createTankWithTankType(enemyTankType[count], mTileMapInfo);
			enemyTank->setPosition(bornPoint[count]);
			enemyTank->setRotation(180.0f);
			mEnemyTanks->addObject(enemyTank);
		}
		else if (count == 3)	//第四個坦克隨機添加
		{
			int tankTypeIndex = (int)(CCRANDOM_0_1() * 4) % 3;
			Tank* enemyTank = Tank::createTankWithTankType(enemyTankType[tankTypeIndex], mTileMapInfo);
			enemyTank->setPosition(bornPoint[tankTypeIndex]);
			enemyTank->setRotation(180.0f);
			mEnemyTanks->addObject(enemyTank);
		}
	}
}

能夠看到deltaTimes累加時間,超過2秒就開始添加坦克,初始三個坦克從固定位置添加,

而後第四個坦克隨機位置添加。blog


5.實現void EnemyAI::tankAction(float delta),來控制坦克行爲:

void EnemyAI::tankAction(float delta)
{
	CCObject* pObj;
	CCARRAY_FOREACH(mEnemyTanks, pObj)
	{
		Tank* tank = (Tank*)pObj;

		//坦克自動移動,碰到牆壁自動換方向
		int Rotation = tank->getRotation();
		if (!tank->command((enumOrder)(Rotation / 90 + 1)))
		{
			int n = (int)(CCRANDOM_0_1() * 5) % 5;
			if (n != 0)
				tank->command((enumOrder)n);
		}

		//每隔一秒開一次火
		tank->setBulletDelta(tank->getBulletDelta() + delta);
		if (tank->getBulletDelta() > 0.5)
		{
			//開火後,若是子彈在飛行中,歸零計時
			if (tank->command(cmdFire))
			{
				tank->setBulletDelta(0.0);
			}
		}
	}
}
從mEnemyTanks中遍歷坦克對象,而後向固定方向移動,遇到牆壁則隨機換方向移動。

在下面,子彈消失後,隔0.5秒再次發射子彈。


6.最後實現咱們的void EnemyAI::update(float delta),它會在每一幀切換的時候被調用。

void EnemyAI::update(float delta)
{
	//坦克不足4個,補充坦克
	addTank(delta);

	//坦克行爲控制
	tankAction(delta);
}

能夠看到,簡單的調用添加坦克函數和控制坦克行爲函數。


7.下面咱們把敵人的AI類整合到CityScene場景中:

bool  CityScene::init()
{
	CCLayer::init();

	//初始化地圖信息
	char szRound[260];
	sprintf(szRound, "Round%d.tmx", mRound);
	TileMapInfo* tileMapInfo = TileMapInfo::createMapInfoWithFile(szRound);
	CCTMXTiledMap* tmxTileMap = tileMapInfo->getTileMap();
	this->addChild(tmxTileMap);

	//在已有的地圖上,建立玩家坦克
	mPlayerTank[0] = Tank::createTankWithTankType("player2U.png", tileMapInfo);

	//放到地圖中初始化位置
	CCSize tileSize = tmxTileMap->getTileSize();
	CCSize mapSize = tmxTileMap->getContentSize();
	mPlayerTank[0]->setPosition(ccp(mapSize.width / 2 - tileSize.width * 3, tileSize.height));

	//添加虛擬手柄的顯示
	mLayerPanel = Panel::create();
	addChild(mLayerPanel, 3);

	//建立敵人坦克的AI
	mEnemyAI = EnemyAI::createEnemyAIWithTank(mPlayerTank[0]);

	return true;
}

//建立敵人坦克的AI
mEnemyAI = EnemyAI::createEnemyAIWithTank(mPlayerTank[0]);

能夠看到最後面建立了咱們的AI。


8.咱們在場景的update中調用AI的update函數

void CityScene::update(float delta)
{
	CCLayer::update(delta);
	//將控制面板中的mLayerPanel獲取的命令傳給坦克
	if (mPlayerTank[0] != NULL)
		mPlayerTank[0]->command(mLayerPanel->getOrder());

	//調用敵人AI的update
	mEnemyAI->update(delta);
}

到這裏基本的坦克AI構建完成,咱們運行下看看效果:



完整代碼下載地址:

http://download.csdn.net/detail/yincheng01/6764095

相關文章
相關標籤/搜索