1. 程式人生 > >cocos2d x遊戲開發系列教程 坦克大戰遊戲之敵方坦克AI的編寫

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

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow

也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!

               

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

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

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

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);privatevoid addTank
(float delta)
void tankAction(float delta);private: CCArray* mEnemyTanks; Tank* mTank; TileMapInfo* mTileMapInfo; //出現地點 CCPoint bornPoint[3];};
上面目前只新增三種類型的敵方坦克,

在成員變數中,mEnemyTanks存放了所有的坦克,

mTank存放了玩家坦克,最後mTileMapInfo存放了地圖資訊。

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


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

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類指標:

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秒就開始新增坦克,初始三個坦克從固定位置新增,

然後第四個坦克隨機位置新增。


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

           

給我老師的人工智慧教程打call!http://blog.csdn.net/jiangjunshow

這裡寫圖片描述