您好,欢迎访问一九零五行业门户网

cocos2dx A* + tiledMap(改良升级)

此次在之前那篇cocos2dx a* tiledmap文章中新加了些功能并且调整了结构 拥有的功能: 能避开障碍物,搜寻最优路径 优化了行走的路径,使之平滑行走(之前的是瓦片级的, 现在是像素级的, #define precise_search_path 开启精确的路径行走) 添加了人物根据位置会被
此次在之前那篇cocos2dx a* + tiledmap文章中新加了些功能并且调整了结构
拥有的功能:
能避开障碍物,搜寻最优路径
优化了行走的路径,使之平滑行走(之前的是瓦片级的, 现在是像素级的, #define precise_search_path 开启精确的路径行走)
添加了人物根据位置会被物体遮住或遮住物体的功能
添加了点击路面, 到达该点.   点击物体, 可以到达该物体的功能
添加了捡拾物体功能
添加了坐椅子功能
添加了人物的骨骼动画(行走和站立)
pathsearchinfo 搜索路径引擎
player 玩家类
pathsprite 瓦片精灵类
paddle物体类(桌子,椅子等)
mathlogic 数学逻辑类
#pragma once#include staticvalue.h#include pathsprite.h#include mathlogic.h#include cocos2d.h#include #include paddle.husing_ns_cc;class pathsearchinfo:public ccnode//寻路类(主要负责寻路的参数和逻辑){public: pathsearchinfo(cctmxtiledmap* tiledmap);private: int m_playermovestep;//人物当前的行程的索引 std::function m_movedone;//移动结束回调 bool m_issetmovedonecallback; std::function)> m_drawpath;//画线回调 调试用 bool m_issetdrawpathcallback; std::function m_selectobj;//选中物体回调 bool m_issetselectobjcallback; cctmxtiledmap* m_map;//地图 cctmxlayer* m_road;//道路 ccsize m_mapsize;//地图大小 ccsize m_tilesize;//地图的块大小 vector m_openlist;//开放列表(里面存放相邻节点) pathsprite* m_inspectarray[map_width][map_height];//全部需要检测的点 vector m_pathlist;//路径列表 vector m_haveinspectlist;//检测过的列表 pathsprite* m_moveobj;//移动的物体 bool m_enablemove;//是否能移动 bool m_ismoving;//是否正在移动public: cctmxtiledmap* getmap() { return m_map; } void setenablemove(bool isenable) { m_enablemove = isenable; } bool getenablemove() { return m_enablemove; } bool getismoving() { return m_ismoving; } void setmovedonecallback(function& pfunc);//设置回调 void setdrawpathcallback(function)>& pfunc);//设置回调 void setselectcallback(function &pfunc);//设置回调 void initmapobject(const char* layername, const char* objname);////初始化地图里的物体(设置深度,设置物体回调函数) ccpoint getmappositionbyworldposition(ccpoint point);//根据世界坐标得到地图坐标 ccpoint getworldpositionbymapposition(ccpoint point);//根据地图坐标得到世界坐标 void pathfunction( ccpoint point, pathsprite* obj );//计算路径函数private: void calculatepath();//计算路径 float calculatetwoobjdistance(pathsprite* obj1, pathsprite* obj2);//计算两个物体间的距离 void inspecttheadjacentnodes(pathsprite* node, pathsprite* adjacent, pathsprite* endnode);//把相邻的节点放入开放节点中 pathsprite* getminpathformopenlist();//从开放节点中获取f值最小值的点 pathsprite* getobjfrominspectarray(int x, int y);//根据横纵坐标从检测数组中获取点 bool removeobjfromopenlist( pathsprite* sprite);//从开放列表中移除对象 void resetinspectarray();//重置检测列表 bool detectwhethercanpassbetweentwopoints(ccpoint p1, ccpoint p2);//检测2个位置中是否有障碍物 void resetobjposition();//重置玩家位置 void clearpath();//清除路径 void moveobj();//移动实现函数};
#include pathsearchinfo.hpathsearchinfo::pathsearchinfo( cctmxtiledmap* tiledmap ){ memset(m_inspectarray, null, map_width*map_height*sizeof(pathsprite*)); m_issetmovedonecallback = false; m_issetdrawpathcallback = false; m_issetselectobjcallback = false; m_enablemove = true; m_map = tiledmap; m_mapsize = m_map->getmapsize();//获取地图的尺寸 地图单位 m_tilesize = m_map->gettilesize();//获取瓦片的尺寸 世界单位 m_road = m_map->layernamed(road);//行走路径的地图 for (int j = 0; j tileat(ccpoint(i, j)); if (_sp) { pathsprite* _pathsprite = new pathsprite(_sp); _pathsprite->m_x = i; _pathsprite->m_y = j; m_inspectarray[i][j] = _pathsprite;//把地图中所有的点一一对应放入检测列表中 } } } }void pathsearchinfo::setmovedonecallback( function& pfunc ){ m_movedone = pfunc; m_issetmovedonecallback = true;}void pathsearchinfo::setdrawpathcallback( function)>& pfunc ){ m_drawpath = pfunc; m_issetdrawpathcallback = true;}void pathsearchinfo::setselectcallback( function &pfunc ){ m_selectobj = pfunc; m_issetselectobjcallback = true;}void pathsearchinfo::initmapobject( const char* layername, const char* objname ){ //图片层 cctmxlayer* _layer = m_map->layernamed(layername); if (!_layer) { return; } //对象层 cctmxobjectgroup* pipegroup = m_map->objectgroupnamed(objname); if (!pipegroup) { return; } //得到所有的对象 ccarray* _array = pipegroup->getobjects(); ccobject *_obj; ccarray_foreach(_array, _obj ) { //得一个 ccdictionary* _dictionary = (ccdictionary*)_obj; //得到属性 float _x = ((ccstring*)_dictionary->objectforkey(x))->floatvalue();//世界单位 float _y= ((ccstring*)_dictionary->objectforkey(y))->floatvalue(); float _widht = ((ccstring*)_dictionary->objectforkey(width))->floatvalue();//世界单位 float _height = ((ccstring*)_dictionary->objectforkey(height))->floatvalue(); ccstring* _terminalx = ((ccstring*)_dictionary->objectforkey(terminalx));//终点x坐标 ccstring* _terminaly = ((ccstring*)_dictionary->objectforkey(terminaly));//终点y坐标 ccstring* _type = ((ccstring*)_dictionary->objectforkey(type));//物体类型 ccstring* _enablesit = ((ccstring*)_dictionary->objectforkey(enablesit));//是否能坐下 ccstring* _enabletouch =(( ccstring*)_dictionary->objectforkey(enabletouch));//是否能触摸 ccstring* _enablepickup =(( ccstring*)_dictionary->objectforkey(enablepickup));//是否能触摸 paddle* _parent = paddle::paddlewithcontentsize(ccsize(_widht, _height));//创建一个物体类 //设置物体属性 if (_terminalx && _terminaly) { _parent->m_terminal = ccpoint( _terminalx->floatvalue(), _terminaly->floatvalue()); if (m_issetselectobjcallback) { _parent->m_selectcallback =m_selectobj; } } else { _parent->m_terminal = ccpoint(-1, -1); } _parent->m_type = _type? (objtype)_type->intvalue():none_type; _parent->m_enablesit = _enablesit? _enablesit->boolvalue():false; _parent->m_enabletouch = _enabletouch?_enabletouch->boolvalue():false; if (_enablepickup) { _parent->m_enablepickup = _enablepickup->boolvalue(); _parent->m_selectcallback =m_selectobj; } else { _parent->m_enablepickup =false; } //设置物体位置 ccpoint _offset = ccpoint(_x, _y );//偏移量 _parent->setposition(_offset); _parent->setanchorpoint(ccpoint(0,0)); for (int i = 0; i tileat(ccpoint(_x/m_tilesize.width+i,m_mapsize.height-1-_y/m_tilesize.height-j)); if (_sprite) { _sprite->retain(); _sprite->removefromparent(); _sprite->setposition(_sprite->getposition()-_offset); _parent->addchild(_sprite); _sprite->release();#if 0//测试该物体 ccmoveby* action = ccmoveby::create(1,ccpoint(0,50)); ccmoveby* actionr = ccmoveby::create(1,ccpoint(0,-50)); ccsequence* seq = ccsequence::create(action, actionr, null); _sprite->runaction(ccrepeatforever::create(seq));#endif } } } //设置对象深度 if (_parent->m_enablepickup) { m_map->addchild(_parent, base_zoder - getworldpositionbymapposition(m_mapsize).y ); } else { m_map->addchild(_parent, base_zoder - _y ); } }} void pathsearchinfo::pathfunction( ccpoint point, pathsprite* obj ){ if (!m_enablemove) { return; } if (point.x m_endx = _sp->m_x; obj->m_endy = _sp->m_y; //计算路径 calculatepath(); resetinspectarray(); //移动物体 moveobj(); //绘制路径 if (m_issetdrawpathcallback) { m_drawpath(m_pathlist); } }}void pathsearchinfo::calculatepath(){#ifdef precise_search_path //得到开始点的节点 pathsprite* _endnode= m_inspectarray[m_moveobj->m_startx][m_moveobj->m_starty]; //得到结束点的节点 pathsprite* _startnode = m_inspectarray[m_moveobj->m_endx][m_moveobj->m_endy]; //因为是开始点 把到起始点的距离设为0, f值也为0 _startnode->m_costtosource = 0; _startnode->m_fvalue = 0; //把已经检测过的点从检测列表中删除 m_inspectarray[m_moveobj->m_endx][m_moveobj->m_endy] = null; //把该点放入已经检测过点的列表中 m_haveinspectlist.push_back(_startnode); //然后加入开放列表 m_openlist.push_back(_startnode); pathsprite* _node = null; while (true) { //得到离起始点最近的点(如果是第一次执行, 得到的是起点) _node = getminpathformopenlist(); if (!_node) { //找不到路径 break; } //把计算过的点从开放列表中删除 removeobjfromopenlist( _node); int _x = _node->m_x; int _y = _node->m_y; // if (_x ==m_moveobj->m_startx && _y == m_moveobj->m_starty) { break; } //检测8个方向的相邻节点是否可以放入开放列表中 pathsprite* _adjacent = null; _adjacent = getobjfrominspectarray( _x +1, _y); inspecttheadjacentnodes(_node, _adjacent, _endnode); _adjacent = getobjfrominspectarray( _x , _y -1); inspecttheadjacentnodes(_node, _adjacent, _endnode); _adjacent = getobjfrominspectarray( _x -1, _y); inspecttheadjacentnodes(_node, _adjacent, _endnode); _adjacent = getobjfrominspectarray( _x , _y+1); inspecttheadjacentnodes(_node, _adjacent, _endnode); _adjacent = getobjfrominspectarray( _x + 1, _y + 1); inspecttheadjacentnodes(_node, _adjacent, _endnode); _adjacent = getobjfrominspectarray( _x +1, _y-1); inspecttheadjacentnodes(_node, _adjacent, _endnode); _adjacent = getobjfrominspectarray( _x -1, _y - 1); inspecttheadjacentnodes(_node, _adjacent, _endnode); _adjacent = getobjfrominspectarray( _x -1, _y+1); inspecttheadjacentnodes(_node, _adjacent, _endnode); } while (_node) { //把路径点加入到路径列表中 //m_pathlist.insert(m_pathlist.begin(), _node); m_pathlist.push_back(_node); _node = _node->m_parent; }#else //得到开始点的节点 pathsprite* _startnode = m_inspectarray[m_moveobj->m_startx][m_moveobj->m_starty]; //得到结束点的节点 pathsprite* _endnode = m_inspectarray[m_moveobj->m_endx][m_moveobj->m_endy]; //因为是开始点 把到起始点的距离设为0, f值也为0 _startnode->m_costtosource = 0; _startnode->m_fvalue = 0; //把已经检测过的点从检测列表中删除 m_inspectarray[m_moveobj->m_startx][m_moveobj->m_starty] = null; //把该点放入已经检测过点的列表中 m_haveinspectlist.push_back(_startnode); //然后加入开放列表 m_openlist.push_back(_startnode); pathsprite* _node = null; while (true) { //得到离起始点最近的点(如果是第一次执行, 得到的是起点) _node = getminpathformopenlist(); if (!_node) { //找不到路径 break; } //把计算过的点从开放列表中删除 removeobjfromopenlist( _node); int _x = _node->m_x; int _y = _node->m_y; // if (_x ==m_moveobj->m_endx && _y == m_moveobj->m_endy) { break; } //检测8个方向的相邻节点是否可以放入开放列表中 pathsprite* _adjacent = null; _adjacent = getobjfrominspectarray( _x +1, _y); inspecttheadjacentnodes(_node, _adjacent, _endnode); _adjacent = getobjfrominspectarray( _x , _y -1); inspecttheadjacentnodes(_node, _adjacent, _endnode); _adjacent = getobjfrominspectarray( _x -1, _y); inspecttheadjacentnodes(_node, _adjacent, _endnode); _adjacent = getobjfrominspectarray( _x , _y+1); inspecttheadjacentnodes(_node, _adjacent, _endnode); _adjacent = getobjfrominspectarray( _x + 1, _y + 1); inspecttheadjacentnodes(_node, _adjacent, _endnode); _adjacent = getobjfrominspectarray( _x +1, _y-1); inspecttheadjacentnodes(_node, _adjacent, _endnode); _adjacent = getobjfrominspectarray( _x -1, _y - 1); inspecttheadjacentnodes(_node, _adjacent, _endnode); _adjacent = getobjfrominspectarray( _x -1, _y+1); inspecttheadjacentnodes(_node, _adjacent, _endnode); } while (_node) { //把路径点加入到路径列表中 m_pathlist.insert(m_pathlist.begin(), _node); //m_pathlist.push_back(_node); _node = _node->m_parent; }#endif // precise_search_path}float pathsearchinfo::calculatetwoobjdistance( pathsprite* obj1, pathsprite* obj2 ){ float _x = abs(obj2->m_x - obj1->m_x); float _y = abs(obj2->m_y - obj1->m_y); return _x + _y;}void pathsearchinfo::inspecttheadjacentnodes( pathsprite* node, pathsprite* adjacent, pathsprite* endnode ){ if (adjacent) { float _x = abs(endnode->m_x - adjacent->m_x); float _y = abs(endnode->m_y - adjacent->m_y); float f , g, h1, h2, h3; adjacent->m_costtosource = node->m_costtosource + calculatetwoobjdistance(node, adjacent);//获得累计的路程 g = adjacent->m_costtosource; //三种算法, 感觉h2不错 h1 = _x + _y; h2 = hypot(_x, _y); h3 = max(_x, _y);#if 1 //a*算法 = dijkstra算法 + 最佳优先搜索 f = g + h1;#endif#if 0//dijkstra算法 f = g;#endif#if 0//最佳优先搜索 f = h2;#endif adjacent->m_fvalue = f; adjacent->m_parent = node;//设置父节点 adjacent->m_sprite->setcolor(ccorange);//搜寻过的节点设为橘色(测试用) m_haveinspectlist.push_back(adjacent); node->m_child = adjacent;//设置子节点 pathsearchinfo::m_inspectarray[adjacent->m_x][adjacent->m_y] = null;//把检测过的点从检测列表中删除 pathsearchinfo::m_openlist.push_back(adjacent);//加入开放列表 }}pathsprite* pathsearchinfo::getminpathformopenlist(){ if (m_openlist.size()>0) { pathsprite* _sp =* m_openlist.begin(); for (vector::iterator iter = m_openlist.begin(); iter != m_openlist.end(); iter++) { if ((*iter)->m_fvalue m_fvalue) { _sp = *iter; } } return _sp; } else { return null; }}pathsprite* pathsearchinfo::getobjfrominspectarray( int x, int y ){ if (x >=0 && y >=0 && x ::iterator iter = m_openlist.begin(); iter != m_openlist.end(); iter++) { if (*iter == sprite) { m_openlist.erase(iter); return true; } } return false;} cocos2d::ccpoint pathsearchinfo::getmappositionbyworldposition( ccpoint point ){ return ccpoint((int)(point.x/pathsearchinfo::m_tilesize.width),(int)(pathsearchinfo::m_mapsize.height - point.y/pathsearchinfo::m_tilesize.height) );}cocos2d::ccpoint pathsearchinfo::getworldpositionbymapposition( ccpoint point ){ return ccpoint(pathsearchinfo::m_tilesize.width * point.x, (pathsearchinfo::m_mapsize.height + point.y)*pathsearchinfo::m_tilesize.height);}void pathsearchinfo::resetinspectarray(){ for (vector::iterator iter = m_haveinspectlist.begin(); iter != m_haveinspectlist.end(); iter++) { //(*iter)->m_sprite->setcolor(ccwhite); (*iter)->m_costtosource = 0; (*iter)->m_fvalue = 0; (*iter)->m_parent = null; (*iter)->m_child = null; m_inspectarray[(*iter)->m_x][(*iter)->m_y] = (*iter); }}bool pathsearchinfo::detectwhethercanpassbetweentwopoints( ccpoint p1, ccpoint p2 ){ float _maxx = p1.x>p2.x?p1.x:p2.x; float _maxy = p1.y>p2.y?p1.y:p2.y; float _minx = p1.xgetposition()); ccsprite* _sp = m_road->tileat(_point); if (_sp) { m_moveobj->m_x = _point.x; m_moveobj->m_y = _point.y; } else { ccsprite* _up = m_road->tileat(_point + ccpoint(0, -1)); if (_up) { m_moveobj->m_x = _point.x; m_moveobj->m_y = _point.y - 1; return; } ccsprite* _down = m_road->tileat(_point + ccpoint(0, 1)); if (_down) { m_moveobj->m_x = _point.x; m_moveobj->m_y = _point.y +1; return; } ccsprite* _left = m_road->tileat(_point + ccpoint(-1, 0)); if (_left) { m_moveobj->m_x = _point.x -1; m_moveobj->m_y = _point.y ; return; } ccsprite* _right = m_road->tileat(_point + ccpoint(1, 0)); if (_right) { m_moveobj->m_x = _point.x + 1; m_moveobj->m_y = _point.y ; return; } }#endif // precise}void pathsearchinfo::clearpath( ){ for (vector::iterator iter = m_haveinspectlist.begin(); iter != m_haveinspectlist.end(); iter++) { (*iter)->m_sprite->setcolor(ccwhite); } resetinspectarray(); //把移除了障碍物的地图放入检测列表中 //m_inspectlist = m_maplist; m_openlist.clear(); m_pathlist.clear(); m_haveinspectlist.clear(); m_moveobj->m_startx = m_moveobj->m_x; m_moveobj->m_starty = m_moveobj->m_y; m_moveobj->m_sprite->stopallactions(); m_playermovestep = 0;}void pathsearchinfo::moveobj(){#ifndef precise_search_path m_playermovestep++; m_ismoving = true; //如果运动完毕 if (m_playermovestep >= m_pathlist.size()) { if (m_issetmovedonecallback) { m_ismoving = false; m_movedone(ccpoint((*(m_pathlist.end()-1))->m_x, (*(m_pathlist.end()-1))->m_y)); } return; } //存储当前的移动进程 m_moveobj->m_x = m_pathlist[m_playermovestep]->m_x; m_moveobj->m_y = m_pathlist[m_playermovestep]->m_y; //设置深度 m_moveobj->m_sprite->setzorder(base_zoder - m_pathlist[m_playermovestep]->m_sprite->getpositiony()); //根据路径列表移动人物 ccpoint _terminalposition = m_pathlist[m_playermovestep]->m_sprite->getposition()+m_tilesize/2; float _length = mathlogic::calculatelengthrequiredtwopoint(_terminalposition,m_moveobj->m_sprite->getposition()); m_moveobj->m_sprite->runaction(ccsequence::create(ccmoveto::create(move_speed * _length,_terminalposition), cccallfunc::create(this, sel_callfunc(&pathsearchinfo::moveobj)), null));#else m_ismoving = true; if (m_playermovestep == m_pathlist.size()-1) { //sitchairjudge(); if (m_issetmovedonecallback) { m_ismoving = false; m_movedone(ccpoint((*(m_pathlist.end()-1))->m_x, (*(m_pathlist.end()-1))->m_y)); } return ; } for (int i = 1;i m_x, m_moveobj->m_y), ccpoint(m_pathlist[m_playermovestep]->m_x,m_pathlist[m_playermovestep]->m_y))) { ccpoint _terminalposition = m_pathlist[m_playermovestep]->m_sprite->getposition()+m_tilesize/2; float _length = mathlogic::calculatelengthrequiredtwopoint(_terminalposition,m_moveobj->m_sprite->getposition()); m_moveobj->m_sprite->runaction(ccsequence::create(ccmoveto::create(move_speed * _length,_terminalposition), cccallfunc::create(this, sel_callfunc(&pathsearchinfo::moveobj)), null)); //存储当前的移动进程 m_moveobj->m_x = m_pathlist[m_playermovestep]->m_x; m_moveobj->m_y = m_pathlist[m_playermovestep]->m_y; m_moveobj->m_sprite->setzorder(base_zoder - m_pathlist[m_playermovestep]->m_sprite->getpositiony()); break; } }#endif}
#pragma once#include cocos2d.h#include vector#include cocos-ext.husing namespace std;using_ns_cc;using_ns_cc_ext;class pathsprite {public: pathsprite(ccsprite* sprite):m_parent(null), m_child(null), m_costtosource(0), m_fvalue(0), m_sprite(sprite), m_startx(0), m_starty(0), m_endx(0), m_endy(0) { };public: ccsprite* m_sprite;//包含的瓦片精灵 pathsprite* m_parent;//父节点 pathsprite* m_child;//子节点 float m_costtosource;//到起始点的距离 int m_x;//地图坐标 int m_y; float m_fvalue; int m_startx;//开始点 int m_starty; int m_endx;//结束点 int m_endy;};
#pragma once#include pathsprite.henum walkstate{ walk_left, walk_right, walk_stand};class player:public pathsprite{public: ccarmature *armature; walkstate m_walkstate;public: player(ccsprite* sprite);public: void walkleft(); void walkright(); void stand(); void walking();};
#include player.hplayer::player(ccsprite* sprite):pathsprite(sprite){ //创建一个人物 ccarmaturedatamanager::sharedarmaturedatamanager()->addarmaturefileinfo(demoplayer/demoplayer.exportjson); armature = null; armature = ccarmature::create(demoplayer);//0走路,1开枪,2开枪,3开空枪,4 armature->setanchorpoint(ccpoint(0.7, 0)); sprite->addchild(armature);}void player::walkleft(){ if (m_walkstate == walk_left) { return; } armature->getanimation()->playwithindex(1); armature->setscalex(1); m_walkstate = walk_left;}void player::walkright(){ if (m_walkstate == walk_right) { return; } armature->getanimation()->playwithindex(1); armature->setscalex(-1); m_walkstate = walk_right;}void player::stand(){ if (m_walkstate == walk_stand) { return; } if (m_walkstate == walk_left) { armature->getanimation()->playwithindex(2); armature->setscalex(1); } if (m_walkstate == walk_right) { armature->getanimation()->playwithindex(2); armature->setscalex(-1); } m_walkstate = walk_stand;}void player::walking(){ if (m_endx - m_startx >=0) { walkright(); } else { walkleft(); }}
#ifndef _paddle_h_#define _paddle_h_#include cocos2d.h#include //#include stdafx.h//using namespace std;using_ns_cc;typedef enum tagpaddlestate { kpaddlestategrabbed, kpaddlestateungrabbed} paddlestate; enum objtype{ none_type = 0, chair_left = 1, chair_fron = 2 , chair_right = 3, chair_back = 4};class paddle : public ccsprite, public cctargetedtouchdelegate{public: paddlestate m_state; bool m_isselect; bool m_enablesit; bool m_enabletouch; bool m_enablepickup; ccpoint m_terminal; std::function m_selectcallback; objtype m_type; ccsprite* m_playersprite; ccsprite* m_chairpartsprite;public: paddle(void); virtual ~paddle(void); ccrect rect(); bool initwithtexture(); virtual void onenter(); virtual void onexit(); bool containstouchlocation(ccpoint point); virtual bool cctouchbegan(cctouch* touch, ccevent* event); virtual void cctouchmoved(cctouch* touch, ccevent* event); virtual void cctouchended(cctouch* touch, ccevent* event); virtual ccobject* copywithzone(cczone *pzone); virtual void touchdelegateretain(); virtual void touchdelegaterelease(); static paddle* paddlewithcontentsize(ccsize);//创建物体 void setselect(bool isselect);//选中时 void setopacity(glubyte opacity); void sitchair();//坐下 void standup();//站起 };#endif
#include paddle.h#include filepath.husing namespace std;paddle::paddle(void):m_chairpartsprite(null), m_playersprite(null),m_enablesit(false){}paddle::~paddle(void){}ccrect paddle::rect(){ ccsize s = this->getcontentsize(); return ccrectmake(this->getpositionx(), this->getpositiony(), s.width, s.height);}paddle* paddle::paddlewithcontentsize(ccsize size){ paddle* ppaddle = new paddle(); ppaddle->initwithtexture(); ppaddle->setcontentsize(size); ppaddle->autorelease(); return ppaddle;}bool paddle::initwithtexture(){ if( ccsprite::init() ) { m_state = kpaddlestateungrabbed; } return true;}void paddle::onenter(){ ccdirector* pdirector = ccdirector::shareddirector(); pdirector->gettouchdispatcher()->addtargeteddelegate(this, 0, false); ccsprite::onenter();}void paddle::onexit(){ ccdirector* pdirector = ccdirector::shareddirector(); pdirector->gettouchdispatcher()->removedelegate(this); ccsprite::onexit();} bool paddle::containstouchlocation(ccpoint point){ //cclog(%f, %f, converttonodespacear(point).x, converttonodespacear(point).y); return rect().containspoint((point));}bool paddle::cctouchbegan(cctouch* touch, ccevent* event){ if (m_isselect) { setselect(false); } auto nodeposition = this->getparent()->converttonodespace( touch->getlocation() ); cclog(%f, %f, nodeposition.x, nodeposition.y); if (m_state != kpaddlestateungrabbed) return false; if ( !containstouchlocation(nodeposition) ) return false; cclog(touchsuccess) ; m_state = kpaddlestategrabbed; setselect(true); if (m_selectcallback) { m_selectcallback(m_terminal, this); } //sitchair(); return true;}void paddle::cctouchmoved(cctouch* touch, ccevent* event){ // if it weren't for the touchdispatcher, you would need to keep a reference // to the touch from touchbegan and check that the current touch is the same // as that one. // actually, it would be even more complicated since in the cocos dispatcher // you get ccsets instead of 1 uitouch, so you'd need to loop through the set // in each touchxxx method. ccassert(m_state == kpaddlestategrabbed, paddle - unexpected state!); // ccpoint touchpoint = touch->getlocation(); //setposition( ccp(touchpoint.x, getposition().y) );}ccobject* paddle::copywithzone(cczone *pzone){ this->retain(); return this;}void paddle::cctouchended(cctouch* touch, ccevent* event){ ccassert(m_state == kpaddlestategrabbed, paddle - unexpected state!); m_state = kpaddlestateungrabbed;} void paddle::touchdelegateretain(){ this->retain();}void paddle::touchdelegaterelease(){ this->release();}void paddle::setselect(bool isselect){ ccarray* _array = this->getchildren(); ccobject *_obj; m_isselect = isselect; ccarray_foreach(_array, _obj ) { ccsprite* _sp = (ccsprite *)_obj; if (isselect) { _sp->setcolor(ccred); } else { _sp->setcolor(ccwhite); } }}void paddle::setopacity( glubyte opacity ){ ccarray* _array = this->getchildren(); ccobject *_obj; ccarray_foreach(_array, _obj ) { ccsprite* _sp = (ccsprite *)_obj; _sp->setopacity(opacity); }}void paddle::sitchair(){ switch (m_type) { case none_type: break; case chair_left: { m_playersprite = ccsprite::create(g_chair_left_player); m_playersprite->setanchorpoint(ccpoint()); m_playersprite->setposition(ccpoint(-8,-15)); this->addchild(m_playersprite, 100); m_chairpartsprite= ccsprite::create(g_chair_left_part); m_chairpartsprite->setanchorpoint(ccpoint()); m_chairpartsprite->setposition(ccpoint(-15,-5)); this->addchild(m_chairpartsprite, 100); break; } case chair_fron: break; case chair_right: break; case chair_back: { m_playersprite = ccsprite::create(g_chair_back_player); m_playersprite->setanchorpoint(ccpoint()); m_playersprite->setposition(ccpoint(-15,-5)); this->addchild(m_playersprite); break; } default: break; }}void paddle::standup(){ if (m_playersprite) { m_playersprite->removefromparentandcleanup(true); m_playersprite = null; } if (m_chairpartsprite) { m_chairpartsprite->removefromparentandcleanup(true); m_chairpartsprite = null; }}
//// mathlogic.h// mapgame//// created by tinyult on 14/10/11.////#ifndef __mapgame__mathlogic__#define __mapgame__mathlogic__#include #include cocos2d.husing_ns_cc;class mathlogic{public: //线性方程 一元二次方法 求y static float linearequationwithoneunknown_solveyrequiredx(ccpoint knownpoint1, ccpoint knownpoint2, float x) { float _x1 = knownpoint1.x; float _y1 = knownpoint1.y; float _x2 = knownpoint2.x; float _y2 = knownpoint2.y; float m_p1 = (_y1 -_y2)/(_x1-_x2); float m_p2 = _y1 - m_p1 * _x1; // float m_p1 = (knownpoint1.y -knownpoint2.y)/(knownpoint1.x-knownpoint2.x); // float m_p2 = knownpoint1.y - m_p1 * knownpoint1.x; return m_p1* x + m_p2; } //线性方程 一元二次方法 求x static float linearequationwithoneunknown_solvexrequiredy(ccpoint knownpoint1, ccpoint knownpoint2, float y) { float _x1 = knownpoint1.x; float _y1 = knownpoint1.y; float _x2 = knownpoint2.x; float _y2 = knownpoint2.y; float m_p1 = (_y1 -_y2)/(_x1-_x2); float m_p2 = _y1 - m_p1 * _x1; // float m_p1 = (knownpoint1.y -knownpoint2.y)/(knownpoint1.x-knownpoint2.x); // float m_p2 = knownpoint1.y - m_p1 * knownpoint1.x; return (y - m_p2)/m_p1; } //求点到直线最短路径长度 static float linearequationwithoneunknown_solveshortlenghtrequiredpoint(ccpoint knownpoint1, ccpoint knownpoint2, ccpoint point) { if ((point.x == knownpoint1.x && point.y == knownpoint1.y) || (point.x == knownpoint2.x && point.y == knownpoint2.y)) { return 0; } float _x1 = knownpoint1.x; float _y1 = knownpoint1.y; float _x2 = knownpoint2.x; float _y2 = knownpoint2.y; float m_p1 = (_y1 -_y2)/(_x1-_x2); float m_p2 = _y1 - m_p1 * _x1; ccpoint p1((point.y - m_p2)/m_p1, point.y); ccpoint p2(point.x, m_p1* point.x + m_p2); float offsety = abs( p2.y - point.y); float offsetx = abs(p1.x - point.x); if (offsetx == 0 && offsety == 0) { return 0; } return offsetx * offsety / calculatelengthrequiredtwopoint(p1, p2); } //计算2点距离 static float calculatelengthrequiredtwopoint(ccpoint p1, ccpoint p2) { float _offsetx = abs( p1.x - p2.x); float _offsety =abs( p1.y - p2.y); return sqrt(_offsetx * _offsetx + _offsety * _offsety); } //绝对值 static float abs(float value) { return value>0?value:-value; }};#endif /* defined(__mapgame__mathlogic__) */
#ifndef __helloworld_scene_h__#define __helloworld_scene_h__#include pathsearchinfo.h#include player.hclass paddle;class helloworld : public cocos2d::cclayer{public: // here's a difference. method 'init' in cocos2d-x returns bool, instead of returning 'id' in cocos2d-iphone virtual bool init(); // there's no 'id' in cpp, so we recommend returning the class instance pointer static cocos2d::ccscene* scene(); // a selector callback void menuclosecallback(ccobject* psender); // implement the static node() method manually create_func(helloworld); void onenter(); virtual bool cctouchbegan(cctouch* touch, ccevent* event); virtual void cctouchmoved(cctouch* touch, ccevent* event); virtual void cctouchended(cctouch* touch, ccevent* event); void drawpath(vector& vec);//绘制路径(测试用) void update(float dt);//跟新大地图(行走时, 人不动, 地图跟着人动); void selectobjcallback(ccpoint point, paddle* selectobj);//选择物体回调 void movedone(ccpoint point);//移动结束回调public: pathsearchinfo* m_pathsearch;//寻路引擎类 ccpoint m_orignpoint;//人物的起始点 player* m_player;//人物 paddle* m_currentselect;//当前选中的物品};#endif // __helloworld_scene_h__
#include helloworldscene.h#include paddle.h#include mathlogic.h#include using_ns_cc;ccscene* helloworld::scene(){ // 'scene' is an autorelease object ccscene *scene = ccscene::create(); // 'layer' is an autorelease object helloworld *layer = helloworld::create(); // add layer as a child to scene scene->addchild(layer); // return the scene return scene;}// on init you need to initialize your instancevoid helloworld::onenter(){ ccdirector* pdirector = ccdirector::shareddirector(); pdirector->gettouchdispatcher()->addtargeteddelegate(this, -1, false); cclayer::onenter();}bool helloworld::init(){ ////////////////////////////// // 1. super init first if ( !cclayer::init() ) { return false; } ccsize visiblesize = ccdirector::shareddirector()->getvisiblesize(); ccpoint origin = ccdirector::shareddirector()->getvisibleorigin(); cctmxtiledmap* _map = cctmxtiledmap::create(gamemap.tmx); _map->setposition(ccpoint()); this->addchild(_map); m_pathsearch = new pathsearchinfo(_map); std::function _fun = std::bind(&helloworld::movedone,this,std::placeholders::_1); m_pathsearch->setmovedonecallback(_fun); std::function)> _fundrawpath = std::bind(&helloworld::drawpath,this,std::placeholders::_1); m_pathsearch->setdrawpathcallback(_fundrawpath); std::function _funcselect = std::bind(&helloworld::selectobjcallback,this,std::placeholders::_1,std::placeholders::_2); m_pathsearch->setselectcallback(_funcselect); ///////////////////////////// ccmenuitemsprite* _menuitemsprite = ccmenuitemsprite::create(ccsprite::create(closenormal.png),ccsprite::create(closeselected.png),null,this,sel_menuhandler(&helloworld::menuclosecallback)); ccmenu* _menu = ccmenu::create(_menuitemsprite,null); this->addchild(_menu, 1000); m_currentselect = null; //m_ismoving = false; cclabelttf* plabel = cclabelttf::create(a* + tiledmap, arial, 24); // position the label on the center of the screen plabel->setposition(ccp(origin.x + visiblesize.width/2, origin.y + visiblesize.height - plabel->getcontentsize().height)); // add the label as a child to this layer this->addchild(plabel, 1); this->scheduleupdate(); //设置起始和终点 m_orignpoint = ccdirector::shareddirector()->getwinsize()/2 ;//+ ccsize(0, 100); //创建一个人物 ccsprite* _sp = ccsprite::create(); _sp->setscale(0.08); m_player = new player(_sp); m_player->m_sprite->setopacity(100); m_pathsearch->getmap()->addchild(m_player->m_sprite, base_zoder); m_player->m_sprite->setposition(m_orignpoint);//设置人物的起始的世界坐标 m_player->m_startx =m_pathsearch->getmappositionbyworldposition(m_orignpoint).x; m_player->m_starty =m_pathsearch->getmappositionbyworldposition(m_orignpoint).y; m_player->m_x = m_player->m_startx; m_player->m_y = m_player->m_starty; m_pathsearch->initmapobject(desk, desk); m_pathsearch->initmapobject(chairleft, chairleft); m_pathsearch->initmapobject(chairfront, chairfront); m_pathsearch->initmapobject(chairback, chairback); m_pathsearch->initmapobject(zhuzi, zhuzi); m_pathsearch->initmapobject(goods, goods); return true;}void helloworld::drawpath( vector& vec ){ for (vector::iterator iter = vec.begin(); iter != vec.end(); iter++) { (*iter)->m_sprite->setcolor(ccgreen); }}ccrect getboundingbox(float x, float y, float width, float height){ return ccrect(x - width/2, y - height/2, width, height);}bool helloworld::cctouchbegan(cctouch* touch, ccevent* event){ if (m_pathsearch->getenablemove()) { m_currentselect = null; auto nodeposition = converttonodespace( touch->getlocation() ); m_pathsearch ->pathfunction(m_pathsearch->getmappositionbyworldposition(nodeposition),m_player); } return true;}void helloworld::cctouchmoved(cctouch* touch, ccevent* event){}void helloworld::cctouchended(cctouch* touch, ccevent* event){}void helloworld::menuclosecallback(ccobject* psender){ if (!m_pathsearch->getenablemove()) { m_pathsearch->setenablemove(true); m_currentselect->standup(); m_player->m_sprite->setvisible(true); }}void helloworld::update(float dt){ //移动层 this->setposition(m_orignpoint - m_player->m_sprite->getposition()); if(m_pathsearch->getismoving()) { m_player->walking(); } else { m_player->stand(); }}void helloworld::selectobjcallback( ccpoint point, paddle* selectobj ){ //如果不能移动物体的话, 不能点击其他物体 if (m_pathsearch->getenablemove()) { m_currentselect = selectobj; m_pathsearch ->pathfunction( point ,m_player); }}void helloworld::movedone(ccpoint point){ //判断是有选择的物体 if (m_currentselect) { //判断是否能坐下 if (m_currentselect->m_enablesit/* && point.x == m_currentselect->m_terminal.x&& point.y == m_currentselect->m_terminal.y*/) { m_currentselect->sitchair(); m_pathsearch->setenablemove(false); m_player->m_sprite->setvisible(false); } //判断是否能捡起 if (m_currentselect->m_enablepickup) { m_currentselect->m_enablepickup = false; m_currentselect->runaction(ccsequence::create(ccfadeout::create(0.5), ccremoveself::create(true), null)); m_currentselect = null; } }}
static char* g_chair_left_player = player_1/chair_left_player.png;static char* g_chair_back_player = player_1/chair_back_player.png;static char* g_chair_left_part = player_1/chair_left_part.png;
#define map_width 600//要比tmx中的map大1#define map_height 600#define base_zoder 100000#define move_speed 1/200.0#define precise_search_path//精确的寻 路系统, 需要消耗额外的运算(魔兽争霸级的!)
其它类似信息

推荐信息