最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

【cocos2d

运维笔记admin45浏览0评论

【cocos2d

【cocos2d

谈到地图不少人都说要做地图编辑器了,但是我暂时绕过这一步,如果不用寻路地图就不能移动?寻路就是会绕过障碍物的算法。

我做了一个简单的地图的思想,就是地图分层3层:背景层、可行区域层、遮罩层,但是地图就不寻路了,通过设置可行区域层来

实现地图障碍物的方法。下面看一个视图,我把地图详细的分层了:

 

OK,有了这个思路,大家应该也知道我要怎么做了?代码实现上怎么处理呢?

重点:可行区域层原理是根据点击屏幕上的坐标点来取得这个点是否透明!如果不透明那就不让他进行移动,透明则为不可行区域;

首先感谢一下为我提供取色源码的哥们(firedragonpzy),帮助我实现了这个另类的地图设计;下面我贴一下他的源码,

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

FDPixelSprite.h

View Code

FDPixelSprite.cpp

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

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里面包含了所有的素材资料);

=4012433582&uk=4097703620&third=15

 

我建了一个QQ群:和大家一起分享cocos2dx开发经验【41131516】

 

 

发布评论

评论列表(0)

  1. 暂无评论