日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

【cocos2d-x 手游研发----地图活起来了】

發布時間:2024/9/20 编程问答 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【cocos2d-x 手游研发----地图活起来了】 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

談到地圖不少人都說要做地圖編輯器了,但是我暫時繞過這一步,如果不用尋路地圖就不能移動?尋路就是會繞過障礙物的算法。

我做了一個簡單的地圖的思想,就是地圖分層3層:背景層、可行區域層、遮罩層,但是地圖就不尋路了,通過設置可行區域層來

實現地圖障礙物的方法。下面看一個視圖,我把地圖詳細的分層了:

?

OK,有了這個思路,大家應該也知道我要怎么做了?代碼實現上怎么處理呢?

重點:可行區域層原理是根據點擊屏幕上的坐標點來取得這個點是否透明!如果不透明那就不讓他進行移動,透明則為不可行區域;

首先感謝一下為我提供取色源碼的哥們(firedragonpzy),幫助我實現了這個另類的地圖設計;下面我貼一下他的源碼,

新建了FDPixelSprite.cpp,FDPixelSprite.h代碼如下:

FDPixelSprite.h

// // FDPixelSprite.h // PixelDemo // // Created by firedragonpzy on 13-2-19. // // #ifndef __PixelDemo__FDPixelSprite__ #define __PixelDemo__FDPixelSprite__ #include "cocos2d.h" USING_NS_CC;class FDPixelSprite : public CCSprite, public CCTargetedTouchDelegate { public:FDPixelSprite();virtual ~FDPixelSprite();void onEnter();void onExit();void setimg(CCString Url);FDPixelSprite* create(CCString Url);CCImage* img ;CCRect atlasRect();bool isContainTouchLocation(CCTouch *pTouch);bool ccTouchBegan(CCString thismapurl,CCTouch *pTouch, CCEvent *pEvent);void ccTouchMoved(CCTouch *pTouch, CCEvent *pEvent);void ccTouchEnded(CCTouch *pTouch, CCEvent *pEvent);CC_SYNTHESIZE(const char*, m_pName,Name); };#endif /* defined(__PixelDemo__FDPixelSprite__) */ View Code

FDPixelSprite.cpp

// // FDPixelSprite.cpp // PixelDemo // // Created by firedragonpzy on 13-2-19. // // #include "FDPixelSprite.h" #include "FontChina.h"FDPixelSprite::FDPixelSprite() {} FDPixelSprite::~FDPixelSprite() {}FDPixelSprite* FDPixelSprite::create(CCString Url) {FDPixelSprite *sprite = new FDPixelSprite();if (sprite && sprite->initWithFile(Url.getCString())) {sprite->setName(Url.getCString());sprite->autorelease();return sprite;}CC_SAFE_DELETE(sprite);sprite = NULL;return NULL; }void FDPixelSprite::setimg(CCString Url){img= new CCImage();img->initWithImageFileThreadSafe(CCFileUtils::sharedFileUtils()->fullPathForFilename(Url.getCString()).c_str());}void FDPixelSprite::onEnter() {CCSprite::onEnter();CCDirector::sharedDirector()->getTouchDispatcher()->addTargetedDelegate(this, 0, true); }void FDPixelSprite::onExit() {CCSprite::onExit();CCDirector::sharedDirector()->getTouchDispatcher()->removeDelegate(this); }bool FDPixelSprite::ccTouchBegan(CCString thismapurl,cocos2d::CCTouch *pTouch, cocos2d::CCEvent *pEvent) {if (this->isContainTouchLocation(pTouch) ) {ccColor4B c = {0, 0, 0, 0};CCSize winSize = CCDirector::sharedDirector()->getWinSize();CCPoint touchPoint = pTouch->getLocationInView();CCSize cSize = this->getContentSize();CCPoint point =this->getAnchorPointInPoints();point = ccp(cSize.width - point.x,cSize.height- point.y);CCPoint pos(this->getPositionX() - point.x,winSize.height-this->getPositionY()- point.y);CCPoint localPoint = ccp(touchPoint.x - pos.x,touchPoint.y -pos.y);float scaleFactor = CCDirector::sharedDirector()->getContentScaleFactor();unsigned int x = localPoint.x * scaleFactor, y = localPoint.y * scaleFactor;float _width = this->getContentSize().width*scaleFactor;//This method is currently only supports symmetric image//unsigned char *data_ = this->getTexture()->getFDImageData();//Efficiency of this method is relatively low//CCImage * img = new CCImage();//img->initWithImageFileThreadSafe(CCFileUtils::sharedFileUtils()->fullPathForFilename(thismapurl.getCString()).c_str());unsigned char *data_ = img->getData();unsigned int *pixel = (unsigned int *)data_;pixel = pixel + (y * (int)_width)* 1 + x * 1;c.r = *pixel & 0xff;c.g = (*pixel >> 8) & 0xff;c.b = (*pixel >> 16) & 0xff;c.a = (*pixel >> 24) & 0xff;if (c.a == 0) {CCLog(FontChina::G2U("不可點擊!"));return false;}else{CCLog(FontChina::G2U("可點擊!"));return true;}}return false; }void FDPixelSprite::ccTouchMoved(cocos2d::CCTouch *pTouch, cocos2d::CCEvent *pEvent) {//CCPoint pos = this->getPosition();//CCPoint sub = pTouch->getDelta();//this->setPosition(ccpAdd(pos, sub)); }void FDPixelSprite::ccTouchEnded(cocos2d::CCTouch *pTouch, cocos2d::CCEvent *pEvent) {//CCLog("firedragonpzy:ccTouchEnded"); }CCRect FDPixelSprite::atlasRect() {CCSize cSize = this->getContentSize();CCPoint point = this->getAnchorPointInPoints();return CCRectMake( -point.x, -point.y, cSize.width,cSize.height); }bool FDPixelSprite::isContainTouchLocation(cocos2d::CCTouch *pTouch) {return this->atlasRect().containsPoint(convertTouchToNodeSpaceAR(pTouch)); } View Code

有了他們我們就能判斷地圖上是否可行了。OK廢話不多,繼續走向精彩,詳細解決一下背景層我們應該做些什么東西,有什么內容?

背景層肯定要裝載精靈,把我們之前第二章說的【cocos2d-x 大型ARPG手游研發----精靈的八面玲瓏】精靈加載出來,就可以當主角了。

這里有人說,那其他不帶主角功能的怎么辦?繼承你寫的精靈類拓展成怪物類(智能AI攻擊操作),NPC(任務功能模塊),可拓展行是

杠杠滴,繼承下來NPC都能移動,和你打起來,我的思路是把地圖做成一個大容器,每一塊新地圖繼承一個MapsBase的同時他自己也有

有自己的特殊邏輯和特殊業務;

繼續貼代碼,地圖是這么實現的:

Maps_Diyu.h

#include "cocos2d.h" #include "../Commen/FDPixelSprite.h" #include "../Spirits/SpiritsPlayer.h"USING_NS_CC;class Maps_Diyu :public cocos2d::CCSprite { public:Maps_Diyu(CCLayer* layer,CCString mapsurl,CCString mapsurl_1,int zOrder,CCPoint cp);~Maps_Diyu(void);
  CCSprite
* nowmap;CCSprite* nowmap_zhezhao;//基本數據float lastmove_x,lastmove_y;bool moveMapto(CCPoint cp,FDPixelSprite* mainmap_Touch);CCActionInterval* act_moveto_maps;CCActionInterval* act_moveto_maps_touch; CCActionInterval* act_moveto_maps_zhezhao; private:SpiritsPlayer* role_main;CCAnimate* playdonghua; };

Maps_Diyu.cpp

#include "Maps_Diyu.h" #include "../GameData/GetNPCData.h" #include "../Commen/FontChina.h" #include "../Spirits/SpiritsMonster.h" #include "../Effects/SkillEffects.h"Maps_Diyu::Maps_Diyu(CCLayer* layer,CCString mapsurl,CCString mapsurl_1,int zOrder,CCPoint cp) {act_moveto_maps=NULL;act_moveto_maps_zhezhao=NULL;lastmove_x=0;lastmove_y=0;float map_x , map_y;float center_x,center_y;CCPoint origin = CCDirector::sharedDirector()->getVisibleOrigin();CCSize size = CCDirector::sharedDirector()->getWinSize();nowmap = Maps_Diyu::create(mapsurl.getCString());nowmap_zhezhao = Maps_Diyu::create(mapsurl_1.getCString());center_x = size.width/2;center_y = size.height/2;map_y = nowmap->getAnchorPointInPoints().y+origin.y;map_x = nowmap->getAnchorPointInPoints().x;if(cp.getLength()>0){nowmap->setPosition(cp);nowmap_zhezhao->setPosition(cp);}else{nowmap->setPosition(ccp(map_x,map_y));nowmap_zhezhao->setPosition(ccp(map_x,map_y));}//計算地圖上絕對位置的原點坐標float map_fornpc_x,map_fornpc_y;map_fornpc_x= nowmap->getContentSize().width/2;map_fornpc_y=nowmap->getContentSize().height/2;//主角加載GetNPCData* basedatas = new GetNPCData();basedatas->GetNPCchapter1();basedatas->role_player.nowpoint= CCPointMake(map_fornpc_x+428,map_fornpc_y+480);role_main = new SpiritsPlayer(basedatas->role_player,1,false);role_main->npc->retain();//加載NPCbasedatas->role_mengpo.nowpoint= CCPointMake(map_fornpc_x+158,map_fornpc_y+510);SpiritsPlayer* role_mengpo= new SpiritsPlayer(basedatas->role_mengpo,1,true);nowmap->addChild(role_mengpo->npc, 2); //-------------------------------------------------------nowmap->addChild(role_main->npc, 2,999);layer->addChild(nowmap_zhezhao, zOrder+1);layer->addChild(nowmap, zOrder); }

OK,地圖初始化就加載了這些基礎的數據,這些應該大家都能看懂,下面貼最核心的代碼,如何把他們都關聯起來

并且做移動操作呢??????

/************************* 參數說明: CCPoint cp 可行區域的坐標 mainmap_Touch 可行區域,需要去隨時改變他移動 **************************/ bool Maps_Diyu::moveMapto(CCPoint cp,FDPixelSprite* mainmap_Touch) { float center_x,center_y,move_x,move_y, map_x , map_y ,to_c_x,to_c_y;CCPoint origin = CCDirector::sharedDirector()->getVisibleOrigin();CCSize size = CCDirector::sharedDirector()->getWinSize();center_x = size.width/2;center_y = size.height/2;move_x = center_x-cp.x;move_y = center_y-cp.y;map_x = nowmap->getPositionX();map_y = nowmap->getPositionY();to_c_x = nowmap->getContentSize().width/2;to_c_y = nowmap->getContentSize().height/2+origin.y;map_x = map_x + move_x;map_y = map_y + move_y-origin.y;//計算移動時間,這邊大家可以幫我優化一下//現在就這塊移動時間有一些問題float a1 , b1 ;a1 = fabs(move_x)/size.width;b1 = fabs(move_y)/size.height;float movetime = ((a1+b1)*8);if(movetime<=1){movetime=1;}//這里是精華,主要是處理任意地圖放進來之后,//防止顯示區域超出地圖的長寬,移動到邊界就不能移動了!if(map_x>=to_c_x){map_x = to_c_x;}else if(map_x<=-((nowmap->getContentSize().width/2)-size.width)){map_x =-((nowmap->getContentSize().width/2)-size.width);}if(map_y>=to_c_y){map_y = to_c_y;}else if(map_y <= -((nowmap->getContentSize().height/2)-size.height)){map_y = -((nowmap->getContentSize().height/2)-size.height);}//經典中的經典////主角移動CCPoint role_move_pc = nowmap->convertToNodeSpace(ccp(cp.x,cp.y));//此處需要通過地圖的視角把人物移動的坐標轉化一下。role_main->moveTomap_dir(role_move_pc); role_main->moveTomap_move(movetime,role_move_pc,false);//地圖移動if(map_x!=lastmove_x&&map_y!=lastmove_y){nowmap->stopAction(act_moveto_maps);nowmap_zhezhao->stopAction(act_moveto_maps_zhezhao);mainmap_Touch->stopAllActions();act_moveto_maps = CCMoveTo::create(movetime,ccp((int)map_x,(int)map_y));act_moveto_maps_touch = CCMoveTo::create(movetime,ccp((int)map_x,(int)map_y));act_moveto_maps_zhezhao = CCMoveTo::create(movetime,ccp((int)map_x,(int)map_y));nowmap->runAction(act_moveto_maps);nowmap_zhezhao->runAction(act_moveto_maps_zhezhao);mainmap_Touch->runAction(act_moveto_maps_touch);return true;}else {return false;}}

核心的地方有三處,幫大家分析一下:

第一,就是計算移動時間,我是根據屏幕長寬來計算,這個地方一直是我心結,這個方法效果現在很不好,跑起來

長距離用時長,短距離就很快,所以請大家也幫我優化一下,可以往下貼代碼,

第二,就是計算出地圖移動的區域,你不可能隨便丟一張圖進去,地圖超過邊界會顯示黑色,不能讓黑色顯示出來(除非丟進來的圖小過屏幕地圖);

第三,就是通過地圖移動的標識來進行人物和地圖的移動,在人物移動的時候需要轉化一下成地圖的坐標!

map_x!=lastmove_x&&map_y!=lastmove_y 可移動的標識 act_moveto_maps = CCMoveTo::create(movetime,ccp((int)map_x,(int)map_y)); act_moveto_maps_touch = CCMoveTo::create(movetime,ccp((int)map_x,(int)map_y)); act_moveto_maps_zhezhao = CCMoveTo::create(movetime,ccp((int)map_x,(int)map_y));大家也看到,我移動的時候,移動的是3個層,這下就保證了可行區域也是不停在變動的

然后就是如何傳數據了,幾句話就可以搞定Scene加載的地圖上所有層;

Scene_Diyu.h

#include "cocos2d.h" #include "ToScene.h" #include "../MapSpirits/Maps_Diyu.h" USING_NS_CC; class Scene_Diyu : public CCLayer { public:Scene_Diyu(void);~Scene_Diyu(void);Maps_Diyu* mainmap;FDPixelSprite* mainmap_Touch;void nextCallback(CCObject* pSender);virtual void registerWithTouchDispatcher(void);virtual bool ccTouchBegan(CCTouch *pTouch,CCEvent *pEvent);virtual void ccTouchMoved(CCTouch *pTouch,CCEvent *pEvent);virtual void ccTouchEnded(CCTouch *pTouch,CCEvent *pEvent);virtual void ccTouchCancelled(CCTouch *pTouch,CCEvent *pEvent); }; View Code

Scene_Diyu.cpp

#include "Scene_Diyu.h" #include "../ImagePaths.h" #include "../PublicUI/BaseUI.h"Scene_Diyu::Scene_Diyu(void) {float x,y;CCPoint origin = CCDirector::sharedDirector()->getVisibleOrigin();CCSize size = CCDirector::sharedDirector()->getWinSize();x = size.width;y = size.height;//地圖mainmap = new Maps_Diyu(this,"map_diyu_naihe.jpg","map_diyu_naihe1.png",0,ccp(x/2-308,y/2-486));mainmap_Touch = mainmap_Touch->create("map_diyu_naihe0.png");mainmap_Touch->setimg("map_diyu_naihe0.png");mainmap_Touch->setPosition(ccp(x/2-308,y/2-486));mainmap_Touch->setVisible(false);//是否顯示點擊層 BaseUI* baseui = new BaseUI(this);this->addChild(mainmap_Touch, 0);setTouchEnabled(true); }void Scene_Diyu::registerWithTouchDispatcher() { CCDirector::sharedDirector()->getTouchDispatcher()->addTargetedDelegate(this,0,true); } bool Scene_Diyu::ccTouchBegan(cocos2d::CCTouch *pTouch, cocos2d::CCEvent *pEvent) { if(mainmap_Touch->ccTouchBegan("map_diyu_naihe0.png",pTouch,pEvent)==true){mainmap->moveMapto(pTouch->getLocation(),mainmap_Touch);}return true; } void Scene_Diyu::ccTouchMoved(cocos2d::CCTouch *pTouch, cocos2d::CCEvent *pEvent) { } void Scene_Diyu::ccTouchEnded(cocos2d::CCTouch *pTouch, cocos2d::CCEvent *pEvent) { } void Scene_Diyu::ccTouchCancelled(cocos2d::CCTouch *pTouch, cocos2d::CCEvent *pEvent) { } Scene_Diyu::~Scene_Diyu(void) { }

?

?大家也看到了再Scene里面控制的點擊事件主要就是處理可行區域的:

if(mainmap_Touch->ccTouchBegan("map_diyu_naihe0.png",pTouch,pEvent)==true){mainmap->moveMapto(pTouch->getLocation(),mainmap_Touch);}

好了,大家如果理解,可以自己研究一下自己的方式去實現一下這樣一套,人物移動,地圖移動的原理,當然,我在這里聲明一下

這套實現思路其實是很歪門,另類的,應為他并沒有采用尋路,但是你也不能完全說不采用尋路算法的地圖系統就不行。

跑起來看一下效果截圖:

跑起來后的效果圖!!!

人物被遮罩層遮擋的效果圖!!

這篇就講這么多了,下一篇直接講一下【怪物智能AI的制作】怪物實現追蹤主角,怪物隨機生成怪圈,怪物隨機移動巡邏。

?

?

游戲demo及素材下載地址(demo里面包含了所有的素材資料);

http://pan.baidu.com/share/link?shareid=4012433582&uk=4097703620&third=15

?

我建了一個QQ群:和大家一起分享cocos2dx開發經驗【41131516】

?

?

總結

以上是生活随笔為你收集整理的【cocos2d-x 手游研发----地图活起来了】的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。