Cocos2d-x《雷電大戰》(6) 智能敵機AI來襲--飛行路徑演算法設計與實現(下),cocos2dx

來源:互聯網
上載者:User

Cocos2d-x《雷電大戰》(6) 智能敵機AI來襲--飛行路徑演算法設計與實現(下),cocos2dx

           林炳文Evankaka原創作品。轉載請註明出處http://blog.csdn.net/evankaka

         筆者近來比較忙,所以遊戲更新都很慢,有此網友也一直在催,但是確實是沒辦法。今天5.1有時間,再來把遊戲更新下。

         此文接上文Cocos2d-x《雷電大戰》(6) 智能敵機AI來襲--飛行路徑演算法設計與實現(上) ,還是對遊戲中的敵機路徑進行一個設計和實現。這裡筆者又實現了兩種敵機路線。分別如下:

(1)敵機朝著英雄飛機的位置飛去

(2)左右兩群飛機穿過,其實就是一大群飛機從左至右和從右至左的飛行。

本文效果:

                                       


Cocos2d-x版本:3.4

工程環境:VS30213

一、敵機朝英雄飛機飛行

        首先來講講敵機朝著英雄飛機的位置飛去,這裡就比較簡單,只要擷取了英雄飛機的位置,再加了設定好敵機的初始位置,那麼敵機的飛行路徑就出來了。下面筆者畫了張圖,具體可以看如:

或者如下



      其中英雄飛機的位置我們可以知道,就可以計算a和b的值,並且能得到角度mDegree。這裡的mDegree主要是用來旋轉敵機的,如果不旋轉敵機的話,看起來效果就不怎麼好。

     現在知道原理了,就開始寫代碼來實現吧:

void GameMain::enemyBuild3(float dt){Size winSize = Director::getInstance()->getWinSize();auto spritePlane = Sprite::create("air2.png");//得到精靈寬和高float height = spritePlane->getContentSize().height;float width = spritePlane->getContentSize().width;//設定敵機位於右上方spritePlane->setPosition(Vec2(winSize.width + width / 2, winSize.height + height/2));spritePlane->setScale(0.25);this->addChild(spritePlane);//計算英雄飛機和對角點連起的線與邊界的角度float x = HeroPlane::getInstance()->getPlane()->getPosition().x;float y = HeroPlane::getInstance()->getPlane()->getPosition().y;float a = winSize.width - x;float b = winSize.height - y;// 弧度轉角度float radians = atanf(a / b);float mDegree = CC_RADIANS_TO_DEGREES(radians);spritePlane->setRotation(180+mDegree);//計算敵機的最終位置float endX = winSize.width-(a / b)*winSize.height;float endY = 0;//計算飛行時間float flyVelocity = 200;//運行速度,可以自己控制,每秒所走的像素float flyLen = sqrt((winSize.width - endX)*(winSize.width - endX)+(winSize.height - endY)*(winSize.height - endY));float realFlyDuration = flyLen / flyVelocity;//實際飛行的時間//子彈啟動並執行距離和時間,從飛機處開始運行到螢幕底部auto actionMove = MoveTo::create(realFlyDuration, Point(endX, endY));//子彈執行完動作後進行函數回調,調用移除子彈函數auto actionDone = CallFuncN::create(CC_CALLBACK_1(GameMain::enemyRemove, this));//連續動作Sequence* sequence = Sequence::create(actionMove, actionDone, NULL);//飛機開始跑動spritePlane->runAction(sequence);}
注意,這裡圖片還是沒有最佳化過的,敵機類也還沒有單獨寫一個類,這裡只是簡單實現了下。

然後開一個定時器定時執行這個操作

//每隔0.5S調用一次schedule(schedule_selector(GameMain::enemyBuild3), 0.5f);

好了,現在來看看結果:


敵機能朝著英雄飛機撞去,並能即時改變自己的角度,當然。這個角度是一來就計算好了的。

二、左右群飛的敵機

        左右群飛就是左邊和右邊都有一排飛機,然後同時向左或向右運動。飛機路徑不是問題,最主要的是設定好它們的起始位置,讓它們都能並排一起。原理圖如下:


        這裡要注意的地方就是設定敵機的位置時記得要加上敵機圖片的位移量,Coco2dx中設定精靈位置時預設是以圖片中心點為原點,所以得加上這個位移量。並且它們移動的距離都是一樣的,所以可以用MoveBy來實現,Y軸方向運動為0,X軸方向運動量為螢幕寬+敵機寬度。左右敵機X軸方向運動量不一樣。記得!並且,這裡的 MoveBy的動作只能給一個敵機來使用,如果另一個敵機是相同的動作,那麼就可以用clone()函數,而不用再重新建立一個MoveBy動作。

整體代碼如下:

void GameMain::enemyBuild4(float dt){Size winSize = Director::getInstance()->getWinSize();Point origin = Director::getInstance()->getVisibleOrigin();//產生左邊敵機auto spritePlane1 = Sprite::create("air5.png");auto spritePlane2 = Sprite::create("air5.png");auto spritePlane3 = Sprite::create("air5.png");//產生邊敵機auto spritePlane4 = Sprite::create("air5.png");auto spritePlane5 = Sprite::create("air5.png");auto spritePlane6 = Sprite::create("air5.png");//旋轉的角度spritePlane1->setRotation(90);spritePlane2->setRotation(90);spritePlane3->setRotation(90);spritePlane4->setRotation(-90);spritePlane5->setRotation(-90);spritePlane6->setRotation(-90);//設定縮放//spritePlane1->setScale(0.3);//spritePlane2->setScale(0.3); //   spritePlane3->setScale(0.3);//得到精靈寬和高float height = spritePlane1->getContentSize().height;float width = spritePlane1->getContentSize().width;   //放置敵機位置spritePlane1->setPosition(Vec2(-width / 2, winSize.height - height / 2-10));spritePlane2->setPosition(Vec2(-width / 2, spritePlane1->getPosition().y - 2 * height - 10));spritePlane3->setPosition(Vec2(-width / 2, spritePlane2->getPosition().y - 2 * height - 10));spritePlane4->setPosition(Vec2(winSize.width + width / 2, spritePlane1->getPosition().y - height - 10));spritePlane5->setPosition(Vec2(winSize.width + width / 2, spritePlane4->getPosition().y - 2 * height - 10));spritePlane6->setPosition(Vec2(winSize.width + width / 2, spritePlane5->getPosition().y - 2 * height - 10));//層中加入精靈this->addChild(spritePlane1);this->addChild(spritePlane2);this->addChild(spritePlane3);this->addChild(spritePlane4);this->addChild(spritePlane5);//計算飛行時間float flyVelocity = 200;//運行速度,可以自己控制,每秒所走的像素float flyLen = winSize.width+width;float realFlyDuration = flyLen / flyVelocity;//實際飛行的時間//子彈啟動並執行距離和時間,從飛機處開始運行到螢幕底部auto actionMove1 = MoveBy::create(realFlyDuration, Point(flyLen,0));auto actionMove2 = MoveBy::create(realFlyDuration, Point(-flyLen, 0));//子彈執行完動作後進行函數回調,調用移除子彈函數auto actionDone = CallFuncN::create(CC_CALLBACK_1(GameMain::enemyRemove, this));//連續動作Sequence* sequence1 = Sequence::create(actionMove1, actionDone, NULL);Sequence* sequence2 = Sequence::create(actionMove1->clone(), actionDone, NULL);Sequence* sequence3 = Sequence::create(actionMove1->clone(), actionDone, NULL);Sequence* sequence4 = Sequence::create(actionMove2, actionDone, NULL);Sequence* sequence5 = Sequence::create(actionMove2->clone(), actionDone, NULL);//飛機開始跑動spritePlane1->runAction(sequence1);spritePlane2->runAction(sequence2);spritePlane3->runAction(sequence3);spritePlane4->runAction(sequence4);spritePlane5->runAction(sequence5);}

然後還是相同的原理,開個定時器,來看看效果:

//每隔0.5調用一次schedule(schedule_selector(GameMain::enemyBuild4), 0.5f);
 

兩種飛機一起來:



三、總結

      這裡飛機的路徑設計了四種,因為還沒有進行最佳化,所以記憶體佔用會有點多,後面筆者將會把敵機類全都放在一個Plist中,這樣子記憶體就會小點了。其實,在飛行遊戲中。還有BOSS機,BOSS機的智能AI設計也是一個很好玩。當然,敵機子彈類也很重要,而這一部分的內容將會放在敵機類設計完成之後再來講。下一講中我們將來封裝自己的敵機類。

  林炳文Evankaka原創作品。轉載請註明出處http://blog.csdn.net/evankaka

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.