C++程序設(shè)計及互動多媒體開發(fā) 課件 第9章 Cocos2d-X開發(fā)基礎(chǔ)_第1頁
C++程序設(shè)計及互動多媒體開發(fā) 課件 第9章 Cocos2d-X開發(fā)基礎(chǔ)_第2頁
C++程序設(shè)計及互動多媒體開發(fā) 課件 第9章 Cocos2d-X開發(fā)基礎(chǔ)_第3頁
C++程序設(shè)計及互動多媒體開發(fā) 課件 第9章 Cocos2d-X開發(fā)基礎(chǔ)_第4頁
C++程序設(shè)計及互動多媒體開發(fā) 課件 第9章 Cocos2d-X開發(fā)基礎(chǔ)_第5頁
已閱讀5頁,還剩72頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)

文檔簡介

C++程序設(shè)計第9章Cocos2D-X開發(fā)基礎(chǔ)第1節(jié)Cocos2d-X開發(fā)環(huán)境搭建第2節(jié)游戲案例——宇宙戰(zhàn)記第3節(jié)安卓版發(fā)布第1節(jié)Cocos2d-X開發(fā)環(huán)境搭建Cocos2d-x簡介Cocos2d-x開發(fā)環(huán)境搭建創(chuàng)建項目HelloCocosHelloCocos程序閱讀1.1Cocos2d-x簡介Cocos2D-X是全球知名的開源跨平臺游戲引擎,易學(xué)易用,目前已經(jīng)支持iOS、Android、Windows桌面、MacOSX、Linux、BlackBerry、WindowsPhone等平臺。目前與Unity、虛幻4一起是使用最廣泛的三大游戲引擎開發(fā)語言:C++,LUA典型游戲案例:捕魚達(dá)人、我叫MT、大掌門……Cocos2d-x發(fā)展歷程2008.02Ricardo在阿根廷LosCocos組建游戲開發(fā)團(tuán)隊并開始創(chuàng)建游戲開發(fā)引擎;2008.03在PyCon2008芝加哥宣布了alpha版本(v0.1),命名Loscocos,之后改名為Cocos2d;2011.07發(fā)布了使用Objective-C編寫Cocos2d-iphonev1.0;隨后嘗試了各種平臺和各種語言版本;2010.07王哲創(chuàng)建Cocos2d-x項目,使用C++;2011.07發(fā)布Cocos2d-xv2.0版本Cocos2d-xv3.0Cocos2d-xv4.0……1.2Cocos2d-x開發(fā)環(huán)境搭建講解環(huán)境:Windows10,VS2022MacOS上的環(huán)境搭建,請參考《cocos2d-x4.0環(huán)境搭建Mac版》

(一)準(zhǔn)備工作(1)安裝Python安裝Python配置這個庫需要Python2,官方推薦的是Python2.7。注意:Python3是不行的!(要是安裝過Python3以后的版本,也可以再裝2.7,兩個可以分開用。)設(shè)置Path環(huán)境變量

此電腦—屬性—高級系統(tǒng)設(shè)置—環(huán)境變量—編輯“系統(tǒng)變量”中的Path,加入Python的安裝目錄—重啟電腦檢查Python版本在控制臺中使用命令“python--version”查看(2)安裝CMake安裝CMake去官網(wǎng)下載或問指導(dǎo)老師獲取,本教案安裝CMake3.28安裝過程中選擇添加Path環(huán)境變量檢查CMake版本在控制臺中使用命令“cmake--version”查看(3)設(shè)置VisualStudio確認(rèn)VisualStudio為2015或之后版本,如不是則安裝本教案使用VS2022確認(rèn)以下模塊是否已安裝,未安裝則補(bǔ)裝把VC編譯環(huán)境路徑加到Path環(huán)境變量中?開始欄搜索x86NativeToolsCommandPromptforVS2022,運行?輸入“wherecl”查找出cl的路徑?把路徑加入到Path環(huán)境變量中(二)安裝配置Cocos2d-x下載或向指導(dǎo)老師獲取cocos2d-x-4.0壓縮包;解壓。把解壓目錄放置在適當(dāng)位置(這個位置就將是Cocos2d-x的安裝位置)進(jìn)入cocos2d-x-4.0文件夾,運行setup.py進(jìn)行安裝。安裝過程中會若問NDK和AndroidSDK的路徑,如果沒有,先直接回車。安裝程序運行完后,按提示重啟計算機(jī)重啟完成后,安裝就完成了。驗證一下版本信息cocos--version1.3例9-1創(chuàng)建項目HelloCocos在控制臺中輸入以下命令創(chuàng)建Cocos新項目

格式:cocosnew項目名稱-l語言-d路徑cocosnewHelloCocos-lcpp-dE:\MyProjects在資源管理器中可看到新建成的項目文件夾繼續(xù)在控制臺中使用CMake對項目進(jìn)行編譯

進(jìn)入工程目錄

創(chuàng)建一個名為“win32-build”的目錄,進(jìn)入該目錄

使用Cmake編譯:cmake..-G"VisualStudio172022"-Tv143-Awin32

注意VS版本號,2022是“VisualStudio172022”2019則為“VisualStudio162019”生成工具是v143,要對應(yīng)“設(shè)置VisualStudio”頁中的截圖中紅框cocos2dx只支持32位編譯,要加-Awin32使用VS2022打開win32-build目錄下的工程文件把工程設(shè)為啟動項運行----OK!1.4HelloCocos程序閱讀(1)程序入口main.cpp中intWINAPI_tWinMain(HINSTANCEhInstance,HINSTANCEhPrevInstance,LPTSTRlpCmdLine,intnCmdShow){UNREFERENCED_PARAMETER(hPrevInstance);//沒引用的這個參數(shù)不要給編譯警告UNREFERENCED_PARAMETER(lpCmdLine);//createtheapplicationinstanceAppDelegateapp;returnApplication::getInstance()->run();//實際上的入口是\AppDelegate.cpp}實際的程序入口是applicationDidFinishLaunching()boolAppDelegate::applicationDidFinishLaunching(){//初始化導(dǎo)演autodirector=Director::getInstance();autoglview=director->getOpenGLView();if(!glview){#if(CC_TARGET_PLATFORM==CC_PLATFORM_WIN32)||(CC_TARGET_PLATFORM==CC_PLATFORM_MAC)||(CC_TARGET_PLATFORM==CC_PLATFORM_LINUX)glview=GLViewImpl::createWithRect("HelloCocos",cocos2d::Rect(0,0,

mediumResolutionSize.width,

mediumResolutionSize.height));//改動這兩參數(shù)使窗口變大#elseglview=GLViewImpl::create("HelloCocos");#endifdirector->setOpenGLView(glview);

}//顯示幀率director->setDisplayStats(true);//設(shè)置幀率,如果不調(diào)用此句,默認(rèn)幀率為1.0/60director->setAnimationInterval(1.0f/60);//設(shè)置designresolutionglview->setDesignResolutionSize(designResolutionSize.width,designResolutionSize.height,ResolutionPolicy::NO_BORDER);autoframeSize=glview->getFrameSize();//如果幀高度>中等尺寸if(frameSize.height>mediumResolutionSize.height){director->setContentScaleFactor(MIN(largeResolutionSize.height/designResolutionSize.height,largeResolutionSize.width/designResolutionSize.width));}

//如果幀尺寸>小尺寸

elseif(frameSize.height>smallResolutionSize.height){director->setContentScaleFactor(MIN(mediumResolutionSize.height/designResolutionSize.height,mediumResolutionSize.width/designResolutionSize.width));}//如果幀高度<小尺寸else{director->setContentScaleFactor(MIN(smallResolutionSize.height/designResolutionSize.height,smallResolutionSize.width/designResolutionSize.width));}register_all_packages();//創(chuàng)建場景。這個場景是自動釋放的對象。autoscene=HelloWorld::createScene();//該函數(shù)中會調(diào)用init()//運行場景director->runWithScene(scene);returntrue;}(2)場景初始化init()boolHelloWorld::init(){////////1.先調(diào)用父類的init()if(!Scene::init()){returnfalse;}autovisibleSize=Director::getInstance()->getVisibleSize();Vec2origin=Director::getInstance()->getVisibleOrigin();////////2.增加一個menuitemimage,點擊它可以退出程序autocloseItem=MenuItemImage::create(“CloseNormal.png”,//未點擊時顯示該圖像“CloseSelected.png”,//點擊時顯示該圖像CC_CALLBACK_1(HelloWorld::menuCloseCallback,this));//設(shè)置點擊回調(diào)函數(shù)if(closeItem==nullptr||closeItem->getContentSize().width<=0||closeItem->getContentSize().height<=0){problemLoading("'CloseNormal.png'and'CloseSelected.png'");}else{//創(chuàng)建成功則布置在右下角位置floatx=origin.x+visibleSize.width-closeItem->getContentSize().width/2;floaty=origin.y+closeItem->getContentSize().height/2;closeItem->setPosition(Vec2(x,y));}//創(chuàng)建menu控件。此為一個能自動釋放的對象automenu=Menu::create(closeItem,NULL);menu->setPosition(Vec2::ZERO);this->addChild(menu,1);增加控件的流程:<1>實例化一個控件XXX::create(),里面設(shè)置好圖片,有動作的設(shè)置好回調(diào)函數(shù)<2>計算顯示的位置,設(shè)置位置setPosition()<3>添加到場景中this->addChild()////////3.addyourcodesbelow...////////4.增加一個label顯示文字"HelloCocos2d-x"autolabel=Label::createWithTTF("HelloCocos2d-x","fonts/MarkerFelt.ttf",24);if(label==nullptr){problemLoading("'fonts/MarkerFelt.ttf'");}else{//把label放在屏幕中間label->setPosition(Vec2(origin.x+visibleSize.width/2,origin.y+visibleSize.height-label->getContentSize().height));//把label加入到圖層this->addChild(label,1);}////////5.增加“HelloWorld.png”圖片autosprite=Sprite::create("HelloWorld.png");if(sprite==nullptr){problemLoading("'HelloWorld.png'");}else{//把sprite放到窗口中間sprite->setPosition(Vec2(visibleSize.width/2+origin.x,visibleSize.height/2+origin.y));//把sprite加入到圖層this->addChild(sprite,0);}returntrue;}各控件的更詳細(xì)方法,請參考官方文檔第2節(jié)游戲案例——宇宙戰(zhàn)記創(chuàng)建新項目清除HelloWorld內(nèi)容添加背景圖添加主角戰(zhàn)機(jī)添加敵機(jī)發(fā)射子彈碰撞檢測敵機(jī)發(fā)射子彈主角戰(zhàn)機(jī)中彈切換場景例9-2編寫一個戰(zhàn)機(jī)對戰(zhàn)游戲,如圖。2.1創(chuàng)建新項目按1.3節(jié)的方法創(chuàng)建新項目,新項目起名為SpaceWar完成后,使用VS2022打開win32-build目錄下的工程文件SpaceWar.sln。不要忘記把工程SpaceWar設(shè)為啟動項。修改applicationDidFinishLaunching()中的分辨率,使窗口變大。運行??煽吹紿elloWorld的界面。下面我們將基于這個程序框架進(jìn)行修改。2.2清除HelloWorld內(nèi)容HelloWorldScene.cpp里的init()函數(shù),只留下以下代碼,刪除其他:boolHelloWorld::init(){//////1.superinitfirstif(!Scene::init()){returnfalse;}//////在此增加新代碼returntrue;}2.3添加背景圖準(zhǔn)備一張背景圖,放進(jìn)Resource目錄中修改init函數(shù),增加以下代碼:boolHelloWorld::init(){……//////在此增加新代碼autowinSize=Director::getInstance()->getVisibleSize();autoorigin=Director::getInstance()->getVisibleOrigin();//增加背景圖autospriteBackGround=Sprite::create("space.jpg");if(spriteBackGround==nullptr){problemLoading("'space.jpg'");}else{//把sprite放在窗口中間spriteBackGround->setPosition(Vec2(winSize.width/2+origin.x,winSize.height/2+origin.y));this->addChild(spriteBackGround,0);//增加sprite到圖層}returntrue;}2.4添加主角戰(zhàn)機(jī)準(zhǔn)備一張主角戰(zhàn)機(jī)的圖片PlaneMe.png,放進(jìn)Resource目錄中在HelloWorldScene.h中添加以下代碼:classHelloWorld:publiccocos2d::Scene{......private:cocos2d::Sprite*_player;};繼續(xù)修改init()函數(shù),在前述增加背景圖代碼的后面增加以下代碼:boolHelloWorld::init(){......//增加主角戰(zhàn)機(jī)_player=Sprite::create("planeme.png");_player->setPosition(Vec2(winSize.width*0.1,winSize.height*0.5));//加到靠左邊中間this->addChild(_player);returntrue;}測試,運行繼續(xù)2.5添加敵機(jī)準(zhǔn)備一張敵機(jī)圖片PlaneEnemy.png,放進(jìn)Resource目錄中

添加一個函數(shù)來做此事。在HelloWorldScene.h中添加函數(shù)聲明:classHelloWorld:publiccocos2d::Scene{......CREATE_FUNC(HelloWorld);voidaddEnemy(floatdt);private:cocos2d::Sprite*_player;};注意圖片文件名大小寫要完全一致,否則后面發(fā)布成Android版本后會因為會大小寫不同而找不到圖片素材,從而導(dǎo)致程序運行出錯。本程序中所有的素材文件都要注意此問題。在HelloWorldScene.cpp中添加函數(shù)定義:voidHelloWorld::addEnemy(floatdt){autoenemy=Sprite::create("PlaneEnemy.png");//增加敵機(jī)

autoenemyContentSize=enemy->getContentSize();autoselfContentSize=this->getContentSize();intminY=enemyContentSize.height/2;//最低位置比窗口底部高半個戰(zhàn)機(jī)intmaxY=selfContentSize.height-minY;//最高位置比窗口頂部低半個戰(zhàn)機(jī)intrangeY=maxY-minY;//高度位置取值范圍intrandomY=(rand()%rangeY)+minY;//在取值范圍內(nèi)隨機(jī)取值enemy->setPosition(Vec2(selfContentSize.width+enemyContentSize.width/2,randomY));this->addChild(enemy);//讓敵機(jī)動起來intminDuration=2.0;//計劃從出現(xiàn)處(最右)移到目標(biāo)點(最左)花費的最少時間intmaxDuration=4.0;//計劃從出現(xiàn)處(最右)移到目標(biāo)點(最左)花費的最多時間intrangeDuration=maxDuration-minDuration;;//計劃時間的取值范圍intrandomDuration=(rand()%rangeDuration)+minDuration;//在取值范圍內(nèi)隨機(jī)取值

//定義移動的object//在randomDuration這個時間內(nèi)(2-4秒內(nèi)),讓敵機(jī)從屏幕右邊移動到左邊(有快有慢)autoactionMove=MoveTo::create(randomDuration,Vec2(-enemyContentSize.width/2,randomY));//定義消除的Object。敵機(jī)移出屏幕后被消除,釋放資源。

autoactionRemove=RemoveSelf::create();enemy->runAction(Sequence::create(actionMove,actionRemove,nullptr));}兩個移動類:MoveTo:是在多長時間內(nèi),移動到指定的點。MoveBy:是在當(dāng)前位置移動多少步。移除類:RemoveSelf執(zhí)行動作runAction。通過Sequence來組織,以nullptr結(jié)束

在init()前述中添加主角戰(zhàn)機(jī)的代碼后面繼續(xù)添加以下代碼:boolHelloWorld::init(){……//設(shè)置隨機(jī)種子。因為addEnemy()中用了rand()。如果不執(zhí)行這一步,每次運行程序都會//產(chǎn)生一樣的隨機(jī)數(shù)。

srand((unsignedint)time(nullptr));//每隔1.5秒生成一個怪物。schedule提供一個連續(xù)動作的功能

this->schedule(CC_SCHEDULE_SELECTOR(HelloWorld::addEnemy),1.5);returntrue;}編譯運行??煽吹讲粩嘤行庐a(chǎn)生

敵機(jī)并沖過來。2.6發(fā)射子彈準(zhǔn)備一張子彈圖片BulletMe.png,放進(jìn)Resource目錄中在init()中添加敵機(jī)的代碼后面增加代碼,注冊事件和綁定響應(yīng)函數(shù):boolHelloWorld::init(){……//為發(fā)射子彈注冊事件和綁定處理函數(shù)

//定義觸摸事件的監(jiān)聽器

autoeventListener=EventListenerTouchOneByOne::create();//定義回調(diào)函數(shù)onTouchBegan():手指一碰到屏幕時就被調(diào)用。

eventListener->onTouchBegan=CC_CALLBACK_2(HelloWorld::onTouchBegan,this);//使用EventDispatcher來處理各種各樣的事件,如觸摸和其他鍵盤事件。

this->getEventDispatcher()->addEventListenerWithSceneGraphPriority(eventListener,_player);returntrue;}觸摸事件監(jiān)聽器和回調(diào)函數(shù)兩種觸摸(點擊)事件的監(jiān)聽器:?EventListenerTouchOneByOne:對每個觸摸事件調(diào)用一次回調(diào)方法。?EventListenerTouchAllAtOnce:對所有的觸摸事件調(diào)用一次回調(diào)方法。每個觸摸事件監(jiān)聽器支持4個回調(diào),只需要對關(guān)心的事件綁定?onTouchBegan:手指剛碰到屏幕時被調(diào)用。如果使用EventListenerTouchOneByOne,必須返回true才能獲取另外3個觸摸事件。?onTouchMoved:手指接觸屏幕并移動(保持接觸)時被調(diào)用。?onTouchEnded:手指離開屏幕時被調(diào)用。?onTouchCancelled:在特定的結(jié)束事件處理的環(huán)境中被調(diào)用,比如觸摸時被電話打斷開在HelloWorldScene.h中添加事件處理函數(shù)的聲明:classHelloWorld:publiccocos2d::Scene{......CREATE_FUNC(HelloWorld);voidaddEnemy(floatdt);boolonTouchBegan(cocos2d::Touch*touch,cocos2d::Event*unused_event);private:cocos2d::Sprite*_player;};在HelloWorldScene.cpp中添加函數(shù)定義:boolHelloWorld::onTouchBegan(Touch*touch,Event*unused_event){

Vec2touchLocation=touch->getLocation();//獲取觸摸點的坐標(biāo)Vec2offset=touchLocation-_player->getPosition();//計算觸摸點相對于_player的偏移量。

//不允許向后射擊。

if(offset.x<0){returntrue;}

//在玩家當(dāng)前位置創(chuàng)建一個子彈,將其添加到場景中。

autoprojectile=Sprite::create("BulletMe.png");projectile->setPosition(_player->getPosition());this->addChild(projectile);

//將偏移量轉(zhuǎn)化為單位向量,即長度為1的向量。

offset.normalize();

//將其乘以1500,獲得了一個指向用戶觸摸點方向并保證超出屏幕的向量。

autoshootAmount=offset*1500;

//將此向量疊加到子彈位置上,這樣就有了一個目標(biāo)位置。

autorealDest=shootAmount+projectile->getPosition();

//創(chuàng)建一個動作,將飛鏢在3秒內(nèi)移動到目標(biāo)位置,然后將它從場景中移除。

autoactionMove=MoveTo::create(3.0f,realDest);autoactionRemove=RemoveSelf::create();projectile->runAction(Sequence::create(actionMove,actionRemove,nullptr));returntrue;}編譯,運行。此時主角戰(zhàn)機(jī)已能發(fā)射子彈。2.7碰撞檢測初始化Physics類。要用物理碰撞,需要在init()中加載它boolHelloWorld::init(){//////1.superinitfirstif(!Scene::init()){returnfalse;}//////在此增加新代碼

//初始化Physicsif(!Scene::initWithPhysics()){returnfalse;}autowinSize=Director::getInstance()->getVisibleSize();……}給敵機(jī)加上physicsBody。這樣敵機(jī)精靈對象就承載了物理屬性。在addEnemy()中添加代碼,加載addChild前面:voidHelloWorld::addEnemy(floatdt){......enemy->setPosition(Vec2(selfContentSize.width+enemyContentSize.width/2,randomY));//為敵機(jī)增加physicsBodyautophysicsBody=PhysicsBody::createBox(enemy->getContentSize(),PhysicsMaterial(0.0f,0.0f,0.0f));physicsBody->setDynamic(false);//設(shè)為不受重力影響physicsBody->setContactTestBitmask(0xFFFFFFFF);//設(shè)為能跟所有物體碰撞enemy->setPhysicsBody(physicsBody);this->addChild(enemy);......}同理,給子彈加上physicsBody。在onTouchBegan()中添加代碼,加載addChild前面:boolHelloWorld::onTouchBegan(Touch*touch,Event*unused_event){......projectile->setPosition(_player->getPosition());//為子彈添加physicsBodyautophysicsBody=PhysicsBody::createBox(projectile->getContentSize(),PhysicsMaterial(0.0f,0.0f,0.0f));physicsBody->setDynamic(false);//設(shè)為不受重力影響physicsBody->setContactTestBitmask(0xFFFFFFFF);//設(shè)為能跟所有物體碰撞projectile->setPhysicsBody(physicsBody);projectile->setTag(100);//做一個標(biāo)記,等會方便識別this->addChild(projectile);......}碰撞事件監(jiān)聽器和回調(diào)函數(shù)碰撞(接觸)事件的監(jiān)聽器:?EventListenerPhysicsContact碰撞事件監(jiān)聽器支持4個回調(diào),只需要對關(guān)心的事件綁定?onContactBegin:兩物體剛接觸時被調(diào)用一次。?onContactPreSolve:兩物體接觸時持續(xù)被調(diào)用。?onContactPostSolve:碰撞處理完成后被調(diào)用,此時兩物體還接觸。?onContactSeparate:兩物體分開時被調(diào)用一次。在init()中注冊發(fā)射子彈事件后面增加代碼,注冊碰撞事件和綁定響應(yīng)函數(shù):boolHelloWorld::init(){……this->getEventDispatcher()->addEventListenerWithSceneGraphPriority(eventListener,_player);//為子彈碰撞注冊事件和綁定處理函數(shù)

autocontactListener=EventListenerPhysicsContact::create();contactListener->onContactBegin=CC_CALLBACK_1(HelloWorld::onContactBegin,this);_eventDispatcher->addEventListenerWithSceneGraphPriority(contactListener,this);returntrue;}在HelloWorldScene.h中添加碰撞事件處理函數(shù)的聲明:classHelloWorld:publiccocos2d::Scene{......CREATE_FUNC(HelloWorld);voidaddEnemy(floatdt);

boolonTouchBegan(cocos2d::Touch*touch,cocos2d::Event*unused_event);boolonContactBegin(cocos2d::PhysicsContact&contact);private:cocos2d::Sprite*_player;};在HelloWorldScene.cpp中添加函數(shù)定義:boolHelloWorld::onContactBegin(cocos2d::PhysicsContact&contact){autonodeA=contact.getShapeA()->getBody()->getNode();autonodeB=contact.getShapeB()->getBody()->getNode();

//如果其中一個物體為子彈,刪除另一個if(nodeA&&nodeB){if(nodeA->getTag()==100){//前面對子彈做了個100標(biāo)記,這里靠該標(biāo)記來識別nodeB->removeFromParentAndCleanup(true);}elseif(nodeB->getTag()==100){nodeA->removeFromParentAndCleanup(true);}}returntrue;}編譯,運行。此時子彈已能消滅敵機(jī)。2.8敵機(jī)發(fā)射子彈設(shè)計目標(biāo)敵人在移動的過程中,隨機(jī)位置發(fā)射一枚子彈思路在原來的代碼中,敵機(jī)只有一個MoveTo的Action,我們把它改成MoveTo->shootStar->MoveTo這樣的動作序列。前半段MoveTo的距離隨機(jī)產(chǎn)生。素材準(zhǔn)備一張子彈圖片BulletEnemy.png,放進(jìn)Resource目錄中在HelloWorldScene.cpp中修改addEnemy():voidHelloWorld::addEnemy(floatdt){......this->addChild(enemy);//注釋掉下面兩段//刪除//讓敵機(jī)動起來

//刪除intminDuration=2.0;

//刪除intmaxDuration=4.0;

//刪除intrangeDuration=maxDuration-minDuration;

//intrandomDuration=(rand()%rangeDuration)+minDuration;

//

//刪除//定義移動的object

//刪除//在randomDuration這個時間內(nèi)(2-4秒內(nèi)),讓怪物從屏幕右邊移動到左邊。

//刪除autoactionMove=MoveTo::create(…參數(shù)長,略…);

//刪除//定義消除的Object。怪物移出屏幕后被消除,釋放資源。

//刪除autoactionRemove=RemoveSelf::create();

//刪除enemy->runAction(Sequence::create(actionMove,actionRemove,nullptr));

//增加以下代碼:

//讓敵機(jī)動起來

intmaxX=selfContentSize.width;intrandomX=maxX-(rand()%(int)(maxX/2));//計算敵機(jī)發(fā)射子彈袋隨機(jī)位置floatenemySpeed=150;floatrandomDuration2=(float)randomX/enemySpeed;//敵機(jī)運動第一段的時間floatrandomDuration1=(float)(maxX-randomX)/enemySpeed;//敵機(jī)運動第二段的時間automove1=MoveTo::create(randomDuration1,Vec2(randomX,randomY));//第一段移動automove2=MoveTo::create(randomDuration2,Vec2(-enemyContentSize.width/2,randomY));//第二段移動

//定義消除的Object。怪物移出屏幕后被消除,釋放資源。

autoactionRemove=RemoveSelf::create();

//敵機(jī)發(fā)射子彈autoshootStar=CallFunc::create([=](){//自定義動作

//創(chuàng)建敵人子彈

Sprite*eProjectile=Sprite::create("BulletEnemy.png");eProjectile->setPosition(enemy->getPosition());

//添加敵機(jī)子彈袋physicsBodyautophysicsBody=PhysicsBody::createBox(eProjectile->getContentSize(),PhysicsMaterial(0.0f,0.0f,0.0f));physicsBody->setDynamic(false);//設(shè)置成不受重力影響physicsBody->setCategoryBitmask(3);//設(shè)置自己的碰撞掩碼為0011physicsBody->setContactTestBitmask(4);//設(shè)置用掩碼0100去碰別人。4能跟F碰,不跟3碰eProjectile->setPhysicsBody(physicsBody);eProjectile->setTag(101);//做個標(biāo)記101this->addChild(eProjectile);

//敵機(jī)發(fā)射子彈

floatstarSpeed=130;//敵機(jī)子彈速度floatstarDuration=(float)randomX/starSpeed;//敵機(jī)子彈移動時間autoprojectileMove=MoveTo::create(starDuration,_player->getPosition());//移動動作autoprojectileRemove=RemoveSelf::create();eProjectile->runAction(Sequence::create(projectileMove,projectileRemove,nullptr));});

//敵人發(fā)射子彈時,停頓一下

DelayTime*delay=cocos2d::DelayTime::create(0.05);enemy->runAction(Sequence::create(move1,delay,shootStar,move2,actionRemove,nullptr));}編譯,運行。此時敵機(jī)已能發(fā)射子彈。2.9主角戰(zhàn)機(jī)中彈碰撞檢測再分析。有以下三種情況(1)敵機(jī)的子彈或者敵人碰到主角戰(zhàn)機(jī),游戲結(jié)束。(2)主角戰(zhàn)機(jī)的子彈碰到敵機(jī)或者敵機(jī)的子彈,會將它們都消滅。(3)主角戰(zhàn)機(jī)的子彈對自己是沒影響,敵機(jī)的子彈對自己也沒影響。為實現(xiàn)以上碰撞功能,掩碼設(shè)計如下:角色掩碼設(shè)計二進(jìn)制值主角戰(zhàn)機(jī)setCategoryBitmask(5)0101setContactTestBitmask(1)0001主角戰(zhàn)機(jī)子彈setCategoryBitmask(5)0101setContactTestBitmask(2)0010敵機(jī)setCategoryBitmask(3)0011setContactTestBitmask(1)0001敵機(jī)子彈setCategoryBitmask(3)0011setContactTestBitmask(4)0100根據(jù)上表,在init()中增加主角戰(zhàn)機(jī)的碰撞屬性:boolHelloWorld::init(){......//增加主角戰(zhàn)機(jī)

_player=Sprite::create("planeme.png");_player->setPosition(Vec2(winSize.width*0.1,winSize.height*0.5));//為主角戰(zhàn)機(jī)添加碰撞屬性

autophysicsBody=PhysicsBody::createBox(_player->getContentSize(),PhysicsMaterial(0.0f,0.0f,0.0f));physicsBody->setDynamic(false);physicsBody->setCategoryBitmask(5);physicsBody->setContactTestBitmask(1);_player->setPhysicsBody(physicsBody);_player->setTag(TAG_MY_PLANE);//#defineTAG_MY_PLANE102this->addChild(_player);

......}原來設(shè)置標(biāo)記直接寫整數(shù),改為用宏定義,提高程序可讀性#defineTAG_MY_PROJECTILE100//主角戰(zhàn)機(jī)子彈#defineTAG_ENEMY_PROJECTILE101//敵機(jī)子彈#defineTAG_MY_PLANE102//主角戰(zhàn)機(jī)#defineTAG_ENEMY_PLANE103//敵機(jī)搜索setTag,把所有語句的參數(shù)改為相應(yīng)宏定義修改onContactBegin()中添加主角戰(zhàn)機(jī)被碰的代碼:boolHelloWorld::onContactBegin(cocos2d::PhysicsContact&contact){autonodeA=contact.getShapeA()->getBody()->getNode();autonodeB=contact.getShapeB()->getBody()->getNode();if(nodeA&&nodeB){intnTagA=nodeA->getTag();intnTagB=nodeB->getTag();if(nTagA==TAG_MY_PROJECTILE){nodeB->removeFromParentAndCleanup(true);}elseif(nTagB==TAG_MY_PROJECTILE){nodeA->removeFromParentAndCleanup(true);}

//當(dāng)player碰到碰到敵人或者敵機(jī)的子彈,就該GameOver了

if(nTagA==TAG_MY_PLANE||nTagB==TAG_MY_PLANE){log("Gameover");}}returntrue;}編譯,運行。此時主角戰(zhàn)機(jī)被碰撞到時VS輸出窗口會產(chǎn)生GameOver提示。2.10切換場景在輸出窗口提示GameOver是不合適的。應(yīng)該在界面上顯示GameOver畫面,并讓游戲停止。專門設(shè)計一個GameOver場景,游戲應(yīng)該結(jié)束時,就切換到該場景。在Classes文件夾中,新建一個cpp文件,取名為GameOverScene.cpp同理,在Classes文件夾中,新建一個頭文件,取名為GameOverScene.h把例8-1HelloCocos中的HelloWorldScene.h中的代碼全部拷貝到GameOverScene.h中。把HelloCocos中的HelloWorldScene.cpp中的代碼全部拷貝到GameOverScene.cpp中。把兩個文件中所有“HELLOWORLD”和“HelloWorld”字樣替換成“GAMEOVER”和“GameOver”修改GameOver::init(),修改文字字體和內(nèi)容,刪除HelloWorld圖像:boolGameOver::init(){......//3.addyourcodesbelow...//addalabelshows“GameOver"http://createandinitializealabelautolabel=Label::createWithTTF("GameOver!","fonts/MarkerFelt.ttf",48);

label->setTextColor(Color4B(249,194,111,255));if(label==nullptr){problemLoading("'fonts/MarkerFelt.ttf'");}else{//positionthelabelonthecenterofthescreenlabel->setPosition(Vec2(origin.x+visibleSize.width/2,origin.y+visibleSize.height/2));//addthelabelasachildtothislayerthis->addChild(label,1);}

//刪除//add"GameOver"splashscreen"

//刪除autosprite=Sprite::create("GameOver.png");

//刪除if(sprite==nullptr)

//刪除{

//刪除problemLoading("'GameOver.png'");

//刪除}

//刪除else

//刪除{

//刪除//positionthespriteonthecenterofthescreen

//刪除sprite->setPosition(Vec2(visibleSize.width/2+origin.x,visibleSize.height/2+origin.y));

//刪除//addthespriteasachildtothislayer

//刪除this->addChild(sprite,0);

//刪除}returntrue;}修改HelloWorld::onContactBegin(),切換GameOver場景:boolHelloWorld::onContactBegin(cocos2d::PhysicsContact&contact){......//當(dāng)player碰到碰到敵機(jī)或者敵機(jī)的子彈,切換GameOver場景

if(nTagA==TAG_MY_PLANE||nTagB==TAG_MY_PLANE){log("Gameover");Director::getInstance()->replaceScene(GameOver::createScene());}}returntrue;}編譯,運行。至此主角戰(zhàn)機(jī)被碰撞到時會彈出GameOver場景。----OK!第3節(jié)安卓版發(fā)布發(fā)布準(zhǔn)備導(dǎo)入cocos的測試工程導(dǎo)入SpaceWar工程常見錯誤及解決辦法3.1發(fā)布準(zhǔn)備安裝AndroidStudio以及AndroidSDK下載或向指導(dǎo)老師取得AndroidStudio,安裝。AndroidSDK會一并裝上。新定義一個系統(tǒng)變量ANDROID_SDK_ROOT,寫上AndroidSDK的路徑

下載或向指導(dǎo)老師取得AndroidNDK壓縮文件,不需安裝,解壓,直接拷貝至某個目錄下。在AndroidStudio中填入NDK目錄(在ProjectStructure按鈕--SDKLocation--AndroidNDKlocation)新定義一個系統(tǒng)變量NDK_ROOT,寫上NDK的路徑在path系統(tǒng)變量中加上下面這4個路徑-%ANDROID_SDK_ROOT%\platforms-%ANDROID_SDK_ROOT%\platforms-tools-%ANDROID_SDK_ROOT%\tools-%NDK_ROOT%安裝NDK驗證安裝在cmd中輸入android,出現(xiàn)下面的提示說明安裝成功。3.2導(dǎo)入cocos的測試工程在AndroidStudio中導(dǎo)入HelloCocos工程(例8-1)以作測試。導(dǎo)入時候不要著急操作什么,因為IDE還要安裝編譯Gradle等一些工作等下面的狀態(tài)條顯示已經(jīng)穩(wěn)定了之后,點擊Build->RebuildProject。編譯會持續(xù)幾分鐘至十幾分鐘的時間,直到提示編譯成功。運行測試工程將安卓手機(jī)連接到電腦,手機(jī)上如果有提示,一定要選“傳輸文件”,并且將開發(fā)者模式打開(各個手機(jī)情況不一樣,請自己查找)。在Device欄會看到你手機(jī)的信息。然后點擊右邊的綠色三角箭頭3.3導(dǎo)入SpaceWar工程總體步驟同3.2節(jié)但由于SpaceWar工程多創(chuàng)建了一個GameOver場景。因此要在CMakeLists.txt中加入新增場景文件:在工程根目錄底下有一個CMakeLists.txt。打開,在下面位置加上GameOver場景的.cpp和.h……#addcross-platformssourcefilesandheaderfileslist(APPENDGAME_SOURCEClasses/AppDelegate.cppClasses/HelloWorldScene.cpp

Classes/GameOverScene.cpp

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論