此次在之前那篇cocos2dx A* tiledMap文章中新加了些功能并且调整了结构 拥有的功能: 能避开障碍物,搜寻最优路径 优化了行走的路径,使之平滑行走(之前的是瓦片级的, 现在是像素级的, #define PRECISE_SEARCH_PATH 开启精确的路径行走) 添加了人物根据位置会被
此次在之前那篇cocos2dx A* + tiledMap文章中新加了些功能并且调整了结构
拥有的功能:
能避开障碍物,搜寻最优路径
优化了行走的路径,使之平滑行走(之前的是瓦片级的, 现在是像素级的, #define PRECISE_SEARCH_PATH 开启精确的路径行走)
添加了人物根据位置会被物体遮住或遮住物体的功能
添加了点击路面, 到达该点. 点击物体, 可以到达该物体的功能
添加了捡拾物体功能
添加了坐椅子功能
添加了人物的骨骼动画(行走和站立)
PathSearchInfo 搜索路径引擎
Player 玩家类
PathSprite 瓦片精灵类
Paddle物体类(桌子,椅子等)
MathLogic 数学逻辑类
#pragma%20once#include%20"StaticValue.h"#include%20"PathSprite.h"#include%20"MathLogic.h"#include%20"cocos2d.h"#include%20#include%20"paddle.h"USING_NS_CC;class%20PathSearchInfo:public%20CCNode//寻路类(主要负责寻路的参数和逻辑){public: PathSearchInfo(CCTMXTiledMap*%20tiledMap);private: int%20m_playerMoveStep;//人物当前的行程的索引 std::function%20m_moveDone;//移动结束回调 bool%20m_isSetMoveDoneCallback; std::function<void(vector)>%20m_drawPath;//画线回调%20%20调试用 bool%20m_isSetDrawPathCallback; std::function%20m_selectObj;//选中物体回调 bool%20m_isSetSelectObjCallback; CCTMXTiledMap*%20m_map;//地图 CCTMXLayer*%20m_road;//道路 CCSize%20m_mapSize;//地图大小 CCSize%20m_tileSize;//地图的块大小 vector%20m_openList;//开放列表(里面存放相邻节点) PathSprite*%20m_inspectArray[MAP_WIDTH][MAP_HEIGHT];//全部需要检测的点 vector%20m_pathList;//路径列表 vector%20m_haveInspectList;//检测过的列表 PathSprite*%20m_moveObj;//移动的物体 bool%20m_enableMove;//是否能移动 bool%20m_isMoving;//是否正在移动public: CCTMXTiledMap*%20getMap() { return%20m_map; } void%20setEnableMove(bool%20isEnable) { m_enableMove%20=%20isEnable; } bool%20getEnableMove() { return%20m_enableMove; } bool%20getIsMoving() { return%20m_isMoving; }%20 void%20setMoveDoneCallback(function&%20pFunc);//设置回调 void%20setDrawPathCallback(function<void(vector)>&%20pFunc);//设置回调 void%20setSelectCallback(function%20&pFunc);//设置回调 void%20initMapObject(const%20char*%20layerName,%20const%20char*%20objName);////初始化地图里的物体(设置深度,设置物体回调函数) CCPoint%20getMapPositionByWorldPosition(CCPoint%20point);//根据世界坐标得到地图坐标 CCPoint%20getWorldPositionByMapPosition(CCPoint%20point);//根据地图坐标得到世界坐标 void%20pathFunction(%20CCPoint%20point,%20PathSprite*%20obj%20);//计算路径函数private: void%20calculatePath();//计算路径 float%20calculateTwoObjDistance(PathSprite*%20obj1,%20PathSprite*%20obj2);//计算两个物体间的距离 void%20inspectTheAdjacentNodes(PathSprite*%20node,%20PathSprite*%20adjacent,%20PathSprite*%20endNode);//把相邻的节点放入开放节点中 PathSprite*%20getMinPathFormOpenList();//从开放节点中获取F值最小值的点 PathSprite*%20getObjFromInspectArray(int%20x,%20int%20y);//根据横纵坐标从检测数组中获取点 bool%20removeObjFromOpenList(%20PathSprite*%20sprite);//从开放列表中移除对象 void%20resetInspectArray();//重置检测列表 bool%20detectWhetherCanPassBetweenTwoPoints(CCPoint%20p1,%20CCPoint%20p2);//检测2个位置中是否有障碍物 void%20resetObjPosition();//重置玩家位置 void%20clearPath();//清除路径 void%20moveObj();//移动实现函数};
#include%20"PathSearchInfo.h"PathSearchInfo::PathSearchInfo(%20CCTMXTiledMap*%20tiledMap%20){ memset(m_inspectArray,%20NULL,%20MAP_WIDTH*MAP_HEIGHT*sizeof(PathSprite*)); m_isSetMoveDoneCallback%20=%20false; m_isSetDrawPathCallback%20=%20false; m_isSetSelectObjCallback%20=%20false; m_enableMove%20=%20true; m_map%20=%20tiledMap; m_mapSize%20=%20m_map->getMapSize();//获取地图的尺寸%20地图单位 m_tileSize%20=%20m_map->getTileSize();//获取瓦片的尺寸%20%20世界单位 m_road%20=%20m_map->layerNamed("road");//行走路径的地图 for%20(int%20j%20=%200;%20%20j%20<%20m_mapSize.height;%20j++)%20{ for%20(int%20i%20=%200;%20%20i%20<%20m_mapSize.width;%20i++)%20{ CCSprite*%20_sp%20=%20m_road->tileAt(CCPoint(i,%20j)); if%20(_sp)%20{ PathSprite*%20_pathSprite%20=%20new%20PathSprite(_sp); _pathSprite->m_x%20=%20i; _pathSprite->m_y%20=%20j; m_inspectArray[i][j]%20=%20_pathSprite;//把地图中所有的点一一对应放入检测列表中 } } } }void%20PathSearchInfo::setMoveDoneCallback(%20function&%20pFunc%20){ m_moveDone%20=%20pFunc; m_isSetMoveDoneCallback%20=%20true;}void%20PathSearchInfo::setDrawPathCallback(%20function<void(vector)>&%20pFunc%20){ m_drawPath%20=%20pFunc; m_isSetDrawPathCallback%20=%20true;}void%20PathSearchInfo::setSelectCallback(%20function%20&pFunc%20){ m_selectObj%20=%20pFunc; m_isSetSelectObjCallback%20=%20true;}void%20PathSearchInfo::initMapObject(%20const%20char*%20layerName,%20const%20char*%20objName%20){ //图片层 CCTMXLayer*%20_layer%20=%20m_map->layerNamed(layerName); if%20(!_layer) { return; } //对象层 CCTMXObjectGroup*%20pipeGroup%20=%20m_map->objectGroupNamed(objName); if%20(!pipeGroup) { return; } //得到所有的对象 CCArray*%20_array%20=%20pipeGroup->getObjects(); CCObject%20*_obj; CCARRAY_FOREACH(_array,%20_obj%20) { //得一个 CCDictionary*%20_dictionary%20%20=%20(CCDictionary*)_obj; //得到属性 float%20_x%20=%20((CCString*)_dictionary->objectForKey("x"))->floatValue();//世界单位 float%20_y=%20((CCString*)_dictionary->objectForKey("y"))->floatValue(); float%20_widht%20=%20((CCString*)_dictionary->objectForKey("width"))->floatValue();//世界单位 float%20_height%20=%20((CCString*)_dictionary->objectForKey("height"))->floatValue(); CCString*%20_terminalX%20=%20((CCString*)_dictionary->objectForKey("terminalX"));//终点x坐标 CCString*%20_terminalY%20=%20((CCString*)_dictionary->objectForKey("terminalY"));//终点y坐标 CCString*%20_type%20=%20((CCString*)_dictionary->objectForKey("type"));//物体类型 CCString*%20_enableSit%20=%20((CCString*)_dictionary->objectForKey("enableSit"));//是否能坐下 CCString*%20_enableTouch%20=((%20CCString*)_dictionary->objectForKey("enableTouch"));//是否能触摸 CCString*%20_enablePickUp%20=((%20CCString*)_dictionary->objectForKey("enablePickUp"));//是否能触摸 Paddle*%20_parent%20=%20Paddle::paddleWithContentSize(CCSize(_widht,%20_height));//创建一个物体类 //设置物体属性 if%20(_terminalX%20&&%20_terminalY) { _parent->m_terminal%20=%20CCPoint(%20_terminalX->floatValue(),%20_terminalY->floatValue()); if%20(m_isSetSelectObjCallback) { _parent->m_selectCallback%20=m_selectObj; } } else { _parent->m_terminal%20=%20CCPoint(-1,%20-1); } _parent->m_type%20=%20_type?%20%20(OBJTYPE)_type->intValue():NONE_TYPE; _parent->m_enableSit%20=%20_enableSit?%20_enableSit->boolValue():false; _parent->m_enableTouch%20=%20_enableTouch?_enableTouch->boolValue():false; if%20(_enablePickUp) { _parent->m_enablePickUp%20=%20_enablePickUp->boolValue(); _parent->m_selectCallback%20=m_selectObj; } else { _parent->m_enablePickUp%20=false; } //设置物体位置 CCPoint%20_offset%20=%20CCPoint(_x,%20_y%20%20);//偏移量 _parent->setPosition(_offset); _parent->setAnchorPoint(CCPoint(0,0)); for%20(int%20i%20=%200;%20i%20<%20_widht/m_tileSize.width;%20i++) { for%20(int%20j%20=%200;%20j%20<%20_height/m_tileSize.height;%20j++) { CCSprite*%20_Sprite%20=%20_layer->tileAt(CCPoint(_x/m_tileSize.width+i,m_mapSize.height-1-_y/m_tileSize.height-j)); if%20(_Sprite) { _Sprite->retain(); _Sprite->removeFromParent(); _Sprite->setPosition(_Sprite->getPosition()-_offset); _parent->addChild(_Sprite); _Sprite->release();#if%200//测试该物体 CCMoveBy*%20action%20=%20CCMoveBy::create(1,CCPoint(0,50)); CCMoveBy*%20actionR%20=%20CCMoveBy::create(1,CCPoint(0,-50)); CCSequence*%20seq%20=%20CCSequence::create(action,%20actionR,%20NULL); _Sprite->runAction(CCRepeatForever::create(seq));#endif } } } //设置对象深度 if%20(_parent->m_enablePickUp) { m_map->addChild(_parent,%20BASE_ZODER%20-%20getWorldPositionByMapPosition(m_mapSize).y%20%20); } else { m_map->addChild(_parent,%20BASE_ZODER%20-%20_y%20); } }}%20void%20PathSearchInfo::pathFunction(%20CCPoint%20point,%20PathSprite*%20obj%20){ if%20(!m_enableMove) { return; } if%20(point.x%20<0%20||%20point.ym_endX%20=%20_sp->m_x; obj->m_endY%20=%20_sp->m_y; //计算路径 calculatePath(); resetInspectArray(); //移动物体 moveObj(); //绘制路径 if%20(m_isSetDrawPathCallback) { m_drawPath(m_pathList); } }}void%20PathSearchInfo::calculatePath(){#ifdef%20PRECISE_SEARCH_PATH //得到开始点的节点 PathSprite*%20%20%20%20_endNode=%20m_inspectArray[m_moveObj->m_startX][m_moveObj->m_startY]; //得到结束点的节点 PathSprite*%20%20%20_startNode%20=%20m_inspectArray[m_moveObj->m_endX][m_moveObj->m_endY]; //因为是开始点%20把到起始点的距离设为0,%20F值也为0 _startNode->m_costToSource%20=%200; _startNode->m_FValue%20=%200; //把已经检测过的点从检测列表中删除 m_inspectArray[m_moveObj->m_endX][m_moveObj->m_endY]%20=%20NULL; //把该点放入已经检测过点的列表中 m_haveInspectList.push_back(_startNode); //然后加入开放列表 m_openList.push_back(_startNode); PathSprite*%20_node%20=%20NULL; while%20(true) { //得到离起始点最近的点(如果是第一次执行,%20得到的是起点) _node%20=%20getMinPathFormOpenList(); if%20(!_node) { //找不到路径 break; } //把计算过的点从开放列表中删除 removeObjFromOpenList(%20_node); int%20_x%20=%20_node->m_x; int%20_y%20=%20_node->m_y; // if%20(_x%20==m_moveObj->m_startX%20&&%20_y%20==%20m_moveObj->m_startY) { break; } //检测8个方向的相邻节点是否可以放入开放列表中 PathSprite*%20_adjacent%20=%20NULL; _adjacent%20=%20getObjFromInspectArray(%20%20_x%20+1,%20_y); inspectTheAdjacentNodes(_node,%20_adjacent,%20_endNode); _adjacent%20=%20getObjFromInspectArray(%20%20_x%20,%20_y%20-1); inspectTheAdjacentNodes(_node,%20_adjacent,%20_endNode); _adjacent%20=%20getObjFromInspectArray(%20%20_x%20-1,%20_y); inspectTheAdjacentNodes(_node,%20_adjacent,%20_endNode); _adjacent%20=%20getObjFromInspectArray(%20%20_x%20,%20_y+1); inspectTheAdjacentNodes(_node,%20_adjacent,%20_endNode); _adjacent%20=%20getObjFromInspectArray(%20_x%20+%201,%20_y%20+%201); inspectTheAdjacentNodes(_node,%20_adjacent,%20_endNode); _adjacent%20=%20getObjFromInspectArray(%20%20_x%20+1,%20_y-1); inspectTheAdjacentNodes(_node,%20_adjacent,%20_endNode); _adjacent%20=%20getObjFromInspectArray(%20%20_x%20-1,%20_y%20-%201); inspectTheAdjacentNodes(_node,%20_adjacent,%20_endNode); _adjacent%20=%20getObjFromInspectArray(%20%20_x%20-1,%20_y+1); inspectTheAdjacentNodes(_node,%20_adjacent,%20_endNode); } while%20(_node) { //把路径点加入到路径列表中 //m_pathList.insert(m_pathList.begin(),%20_node); m_pathList.push_back(_node); _node%20=%20_node->m_parent; }#else //得到开始点的节点 PathSprite*%20%20%20_startNode%20=%20m_inspectArray[m_moveObj->m_startX][m_moveObj->m_startY]; //得到结束点的节点 PathSprite*%20%20_endNode%20=%20m_inspectArray[m_moveObj->m_endX][m_moveObj->m_endY]; //因为是开始点%20把到起始点的距离设为0,%20F值也为0 _startNode->m_costToSource%20=%200; _startNode->m_FValue%20=%200; //把已经检测过的点从检测列表中删除 m_inspectArray[m_moveObj->m_startX][m_moveObj->m_startY]%20=%20NULL; //把该点放入已经检测过点的列表中 m_haveInspectList.push_back(_startNode); //然后加入开放列表 m_openList.push_back(_startNode); PathSprite*%20_node%20=%20NULL; while%20(true) { //得到离起始点最近的点(如果是第一次执行,%20得到的是起点) _node%20=%20getMinPathFormOpenList(); if%20(!_node) { //找不到路径 break; } //把计算过的点从开放列表中删除 removeObjFromOpenList(%20_node); int%20_x%20=%20_node->m_x; int%20_y%20=%20_node->m_y; // if%20(_x%20==m_moveObj->m_endX%20&&%20_y%20==%20m_moveObj->m_endY) { break; } //检测8个方向的相邻节点是否可以放入开放列表中 PathSprite*%20_adjacent%20=%20NULL; _adjacent%20=%20getObjFromInspectArray(%20%20_x%20+1,%20_y); inspectTheAdjacentNodes(_node,%20_adjacent,%20_endNode); _adjacent%20=%20getObjFromInspectArray(%20%20_x%20,%20_y%20-1); inspectTheAdjacentNodes(_node,%20_adjacent,%20_endNode); _adjacent%20=%20getObjFromInspectArray(%20%20_x%20-1,%20_y); inspectTheAdjacentNodes(_node,%20_adjacent,%20_endNode); _adjacent%20=%20getObjFromInspectArray(%20%20_x%20,%20_y+1); inspectTheAdjacentNodes(_node,%20_adjacent,%20_endNode); _adjacent%20=%20getObjFromInspectArray(%20_x%20+%201,%20_y%20+%201); inspectTheAdjacentNodes(_node,%20_adjacent,%20_endNode); _adjacent%20=%20getObjFromInspectArray(%20%20_x%20+1,%20_y-1); inspectTheAdjacentNodes(_node,%20_adjacent,%20_endNode); _adjacent%20=%20getObjFromInspectArray(%20%20_x%20-1,%20_y%20-%201); inspectTheAdjacentNodes(_node,%20_adjacent,%20_endNode); _adjacent%20=%20getObjFromInspectArray(%20%20_x%20-1,%20_y+1); inspectTheAdjacentNodes(_node,%20_adjacent,%20_endNode); } while%20(_node) { //把路径点加入到路径列表中 m_pathList.insert(m_pathList.begin(),%20_node); //m_pathList.push_back(_node); _node%20=%20_node->m_parent; }#endif%20//%20PRECISE_SEARCH_PATH}float%20PathSearchInfo::calculateTwoObjDistance(%20PathSprite*%20obj1,%20PathSprite*%20obj2%20){ float%20_x%20=%20abs(obj2->m_x%20-%20obj1->m_x); float%20_y%20=%20abs(obj2->m_y%20-%20obj1->m_y); return%20_x%20+%20_y;}void%20PathSearchInfo::inspectTheAdjacentNodes(%20PathSprite*%20node,%20PathSprite*%20adjacent,%20PathSprite*%20endNode%20){ if%20(adjacent) { float%20_x%20=%20abs(endNode->m_x%20-%20adjacent->m_x); float%20_y%20=%20abs(endNode->m_y%20-%20adjacent->m_y); float%20F%20,%20G,%20H1,%20H2,%20H3; adjacent->m_costToSource%20=%20node->m_costToSource%20+%20calculateTwoObjDistance(node,%20adjacent);//获得累计的路程 G%20=%20adjacent->m_costToSource; //三种算法,%20感觉H2不错 H1%20=%20_x%20+%20_y; H2%20=%20hypot(_x,%20_y); H3%20=%20max(_x,%20_y);#if%201%20//A*算法%20=%20Dijkstra算法%20+%20最佳优先搜索 F%20=%20G%20+%20H1;#endif#if%200//Dijkstra算法 F%20=%20G;#endif#if%200//最佳优先搜索 F%20=%20H2;#endif adjacent->m_FValue%20=%20F; adjacent->m_parent%20=%20node;//设置父节点 adjacent->m_sprite->setColor(ccORANGE);//搜寻过的节点设为橘色(测试用) m_haveInspectList.push_back(adjacent); node->m_child%20=%20adjacent;//设置子节点 PathSearchInfo::m_inspectArray[adjacent->m_x][adjacent->m_y]%20=%20NULL;//把检测过的点从检测列表中删除 PathSearchInfo::m_openList.push_back(adjacent);//加入开放列表 }}PathSprite*%20PathSearchInfo::getMinPathFormOpenList(){ if%20(m_openList.size()>0)%20{ PathSprite*%20_sp%20=*%20m_openList.begin(); for%20(vector::iterator%20iter%20=%20m_openList.begin();%20iter%20!=%20%20m_openList.end();%20iter++) { if%20((*iter)->m_FValue%20<%20_sp->m_FValue) { _sp%20=%20*iter; } } return%20_sp; } else { return%20NULL; }}PathSprite*%20PathSearchInfo::getObjFromInspectArray(%20int%20x,%20int%20y%20){ if%20(x%20>=0%20&&%20y%20>=0%20&&%20x%20<%20m_mapSize.width%20&&%20y%20<%20m_mapSize.height)%20{ return%20m_inspectArray[x][y]; } return%20%20NULL;}bool%20PathSearchInfo::removeObjFromOpenList(%20PathSprite*%20sprite%20){ if%20(!sprite)%20{ return%20%20false; } for%20(vector::iterator%20iter%20=%20m_openList.begin();%20iter%20!=%20%20m_openList.end();%20iter++) { if%20(*iter%20==%20sprite) { m_openList.erase(iter); return%20true; } } return%20false;}%20%20cocos2d::CCPoint%20PathSearchInfo::getMapPositionByWorldPosition(%20CCPoint%20point%20){ return%20CCPoint((int)(point.x/PathSearchInfo::m_tileSize.width),(int)(PathSearchInfo::m_mapSize.height%20-%20point.y/PathSearchInfo::m_tileSize.height)%20);}cocos2d::CCPoint%20PathSearchInfo::getWorldPositionByMapPosition(%20CCPoint%20point%20){ return%20CCPoint(PathSearchInfo::m_tileSize.width%20*%20point.x,%20(PathSearchInfo::m_mapSize.height%20+%20point.y)*PathSearchInfo::m_tileSize.height);}void%20PathSearchInfo::resetInspectArray(){ for%20(vector::iterator%20iter%20=%20m_haveInspectList.begin();%20iter%20!=%20m_haveInspectList.end();%20iter++) { //(*iter)->m_sprite->setColor(ccWHITE); (*iter)->m_costToSource%20=%200; (*iter)->m_FValue%20=%200; (*iter)->m_parent%20=%20NULL; (*iter)->m_child%20=%20NULL; m_inspectArray[(*iter)->m_x][(*iter)->m_y]%20=%20(*iter); }}bool%20PathSearchInfo::detectWhetherCanPassBetweenTwoPoints(%20CCPoint%20p1,%20CCPoint%20p2%20){%20 float%20_maxX%20=%20p1.x>p2.x?p1.x:p2.x; float%20_maxY%20=%20p1.y>p2.y?p1.y:p2.y; float%20_minX%20=%20p1.x<p2.x?p1.x:p2.x; float%20_minY%20=%20p1.y1) { return%20false; } float%20_x%20=%20p1.x; for%20(int%20_y%20=%20_minY;%20_y%20%201) { return%20false; } float%20_y%20=%20p1.y; for%20(int%20_x%20=%20_minX;%20_x%20<=_maxX;%20_x++%20) { PathSprite*_sp%20=%20m_inspectArray[(int)_x][(int)(_y)]; if%20(!_sp) { return%20false; }%20 } } else { for%20(int%20_y%20=%20_minY;%20_y%20<=%20_maxY;%20_y++) { for%20(int%20_x%20=%20_minX;%20_x%20m_sprite->getPosition()); CCSprite*%20_sp%20=%20m_road->tileAt(_point); if%20(_sp) { m_moveObj->m_x%20=%20_point.x; m_moveObj->m_y%20=%20_point.y; }%20 else { CCSprite*%20_up%20=%20m_road->tileAt(_point%20+%20CCPoint(0,%20-1)); if%20(_up) { m_moveObj->m_x%20=%20_point.x; m_moveObj->m_y%20=%20_point.y%20-%201; return; } CCSprite*%20_down%20=%20m_road->tileAt(_point%20+%20CCPoint(0,%201)); if%20(_down) { m_moveObj->m_x%20=%20_point.x; m_moveObj->m_y%20=%20_point.y%20+1; return; } CCSprite*%20_left%20=%20m_road->tileAt(_point%20+%20CCPoint(-1,%200)); if%20(_left) { m_moveObj->m_x%20=%20_point.x%20-1; m_moveObj->m_y%20=%20_point.y%20; return; } CCSprite*%20_right%20=%20m_road->tileAt(_point%20+%20CCPoint(1,%200)); if%20(_right) { m_moveObj->m_x%20=%20_point.x%20+%201; m_moveObj->m_y%20=%20_point.y%20; return; } }#endif%20//%20PRECISE}void%20PathSearchInfo::clearPath(%20%20){ for%20(vector::iterator%20iter%20=%20m_haveInspectList.begin();%20iter%20!=%20%20m_haveInspectList.end();%20iter++) { (*iter)->m_sprite->setColor(ccWHITE); } resetInspectArray(); //把移除了障碍物的地图放入检测列表中 //m_inspectList%20=%20m_mapList; m_openList.clear(); m_pathList.clear(); m_haveInspectList.clear(); m_moveObj->m_startX%20=%20m_moveObj->m_x; m_moveObj->m_startY%20=%20m_moveObj->m_y; m_moveObj->m_sprite->stopAllActions(); m_playerMoveStep%20=%200;}void%20PathSearchInfo::moveObj(){#ifndef%20PRECISE_SEARCH_PATH m_playerMoveStep++; m_isMoving%20=%20true; //如果运动完毕 if%20(m_playerMoveStep%20>=%20m_pathList.size()) { if%20(m_isSetMoveDoneCallback) { m_isMoving%20=%20false; m_moveDone(CCPoint((*(m_pathList.end()-1))->m_x,%20(*(m_pathList.end()-1))->m_y)); } return; } //存储当前的移动进程 m_moveObj->m_x%20=%20m_pathList[m_playerMoveStep]->m_x; m_moveObj->m_y%20=%20m_pathList[m_playerMoveStep]->m_y; //设置深度 m_moveObj->m_sprite->setZOrder(BASE_ZODER%20-%20m_pathList[m_playerMoveStep]->m_sprite->getPositionY()); //根据路径列表移动人物 CCPoint%20_terminalPosition%20=%20%20m_pathList[m_playerMoveStep]->m_sprite->getPosition()+m_tileSize/2; float%20_length%20=%20%20MathLogic::calculateLengthRequiredTwoPoint(_terminalPosition,m_moveObj->m_sprite->getPosition()); m_moveObj->m_sprite->runAction(CCSequence::create(CCMoveTo::create(MOVE_SPEED%20*%20_length,_terminalPosition),%20CCCallFunc::create(this,%20SEL_CallFunc(&PathSearchInfo::moveObj)),%20NULL));#else m_isMoving%20=%20true; if%20(m_playerMoveStep%20==%20m_pathList.size()-1) { //sitChairJudge(); if%20(m_isSetMoveDoneCallback) { m_isMoving%20=%20false; m_moveDone(CCPoint((*(m_pathList.end()-1))->m_x,%20(*(m_pathList.end()-1))->m_y)); } return%20; } for%20(int%20i%20=%201;i%20m_x,%20m_moveObj->m_y),%20CCPoint(m_pathList[m_playerMoveStep]->m_x,m_pathList[m_playerMoveStep]->m_y))) { CCPoint%20_terminalPosition%20=%20m_pathList[m_playerMoveStep]->m_sprite->getPosition()+m_tileSize/2; float%20_length%20=%20MathLogic::calculateLengthRequiredTwoPoint(_terminalPosition,m_moveObj->m_sprite->getPosition()); m_moveObj->m_sprite->runAction(CCSequence::create(CCMoveTo::create(MOVE_SPEED%20*%20_length,_terminalPosition),%20CCCallFunc::create(this,%20SEL_CallFunc(&PathSearchInfo::moveObj)),%20NULL)); //存储当前的移动进程 m_moveObj->m_x%20=%20m_pathList[m_playerMoveStep]->m_x; m_moveObj->m_y%20=%20m_pathList[m_playerMoveStep]->m_y; m_moveObj->m_sprite->setZOrder(BASE_ZODER%20-%20m_pathList[m_playerMoveStep]->m_sprite->getPositionY()); break; } }#endif}
#pragma%20once#include%20"cocos2d.h"#include%20"vector"#include%20"cocos-ext.h"using%20namespace%20std;USING_NS_CC;USING_NS_CC_EXT;class%20PathSprite%20{public: PathSprite(CCSprite*%20sprite):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*%20m_sprite;//包含的瓦片精灵 PathSprite*%20m_parent;//父节点 PathSprite*%20m_child;//子节点 float%20m_costToSource;//到起始点的距离 int%20m_x;//地图坐标 int%20m_y; float%20m_FValue; int%20m_startX;//开始点 int%20m_startY; int%20m_endX;//结束点 int%20m_endY;};
#pragma%20once#include%20"PathSprite.h"enum%20WalkState{ WALK_LEFT, WALK_RIGHT, WALK_STAND};class%20Player:public%20PathSprite{public: CCArmature%20*armature; WalkState%20m_walkState;public: Player(CCSprite*%20sprite);public: void%20walkLeft(); void%20walkRight(); void%20stand(); void%20walking();};
#include%20"Player.h"Player::Player(CCSprite*%20sprite):PathSprite(sprite){ //创建一个人物 CCArmatureDataManager::sharedArmatureDataManager()->addArmatureFileInfo("DemoPlayer/DemoPlayer.ExportJson"); armature%20=%20NULL; armature%20=%20CCArmature::create("DemoPlayer");//0走路,1开枪,2开枪,3开空枪,4 armature->setAnchorPoint(CCPoint(0.7,%200)); sprite->addChild(armature);}void%20Player::walkLeft(){ if%20(m_walkState%20==%20WALK_LEFT) { return; } armature->getAnimation()->playWithIndex(1); armature->setScaleX(1); m_walkState%20=%20WALK_LEFT;}void%20Player::walkRight(){ if%20(m_walkState%20==%20WALK_RIGHT) { return; } armature->getAnimation()->playWithIndex(1); armature->setScaleX(-1); m_walkState%20=%20WALK_RIGHT;}void%20Player::stand(){ if%20(m_walkState%20==%20WALK_STAND) { return; } if%20(m_walkState%20==%20WALK_LEFT) { armature->getAnimation()->playWithIndex(2); armature->setScaleX(1); } if%20(m_walkState%20==%20WALK_RIGHT) { armature->getAnimation()->playWithIndex(2); armature->setScaleX(-1); } m_walkState%20=%20WALK_STAND;}void%20Player::walking(){ if%20(m_endX%20-%20m_startX%20%20>=0) { walkRight(); } else { walkLeft(); }}
#ifndef%20_PADDLE_H_#define%20_PADDLE_H_#include%20"cocos2d.h"#include%20//#include%20"stdafx.h"//using%20namespace%20std;USING_NS_CC;typedef%20enum%20tagPaddleState%20{ kPaddleStateGrabbed, kPaddleStateUngrabbed}%20PaddleState;%20enum%20OBJTYPE{ NONE_TYPE%20=%200, CHAIR_LEFT%20=%201, CHAIR_FRON%20=%202%20, CHAIR_RIGHT%20=%203, CHAIR_BACK%20=%204};class%20Paddle%20:%20public%20CCSprite,%20public%20CCTargetedTouchDelegate{public: PaddleState%20%20%20%20%20%20%20%20m_state; bool%20m_isSelect; bool%20m_enableSit; bool%20m_enableTouch; bool%20m_enablePickUp; CCPoint%20m_terminal; std::function%20m_selectCallback; OBJTYPE%20m_type; CCSprite*%20m_playerSprite; CCSprite*%20m_chairPartSprite;public: Paddle(void); virtual%20~Paddle(void); CCRect%20rect(); bool%20initWithTexture(); virtual%20void%20onEnter(); virtual%20void%20onExit(); bool%20containsTouchLocation(CCPoint%20point); virtual%20bool%20ccTouchBegan(CCTouch*%20touch,%20CCEvent*%20event); virtual%20void%20ccTouchMoved(CCTouch*%20touch,%20CCEvent*%20event); virtual%20void%20ccTouchEnded(CCTouch*%20touch,%20CCEvent*%20event); virtual%20CCObject*%20copyWithZone(CCZone%20*pZone); virtual%20void%20touchDelegateRetain(); virtual%20void%20touchDelegateRelease(); static%20Paddle*%20paddleWithContentSize(CCSize);//创建物体 void%20setSelect(bool%20isSelect);//选中时 void%20setOpacity(GLubyte%20opacity); void%20sitChair();//坐下 void%20standUp();//站起 };#endif
#include%20"Paddle.h"#include%20"FilePath.h"using%20namespace%20std;Paddle::Paddle(void):m_chairPartSprite(NULL),%20m_playerSprite(NULL),m_enableSit(false){}Paddle::~Paddle(void){}CCRect%20Paddle::rect(){ CCSize%20s%20=%20this->getContentSize(); return%20CCRectMake(this->getPositionX(),%20%20this->getPositionY(),%20s.width,%20s.height);}Paddle*%20Paddle::paddleWithContentSize(CCSize%20size){ Paddle*%20pPaddle%20=%20new%20Paddle(); pPaddle->initWithTexture(); pPaddle->setContentSize(size); pPaddle->autorelease(); return%20pPaddle;}bool%20Paddle::initWithTexture(){ if(%20CCSprite::init()%20) { m_state%20=%20kPaddleStateUngrabbed; } return%20true;}void%20Paddle::onEnter(){ CCDirector*%20pDirector%20=%20CCDirector::sharedDirector(); pDirector->getTouchDispatcher()->addTargetedDelegate(this,%200,%20false); CCSprite::onEnter();}void%20Paddle::onExit(){ CCDirector*%20pDirector%20=%20CCDirector::sharedDirector(); pDirector->getTouchDispatcher()->removeDelegate(this); CCSprite::onExit();}%20%20%20%20bool%20Paddle::containsTouchLocation(CCPoint%20point){ //CCLog("%f,%20%f",%20convertToNodeSpaceAR(point).x,%20convertToNodeSpaceAR(point).y); return%20rect().containsPoint((point));}bool%20Paddle::ccTouchBegan(CCTouch*%20touch,%20CCEvent*%20event){ if%20(m_isSelect)%20{ setSelect(false); } auto%20nodePosition%20=%20this->getParent()->convertToNodeSpace(%20touch->getLocation()%20); CCLog("%f,%20%f",%20nodePosition.x,%20nodePosition.y); if%20(m_state%20!=%20kPaddleStateUngrabbed)%20return%20false; if%20(%20!containsTouchLocation(nodePosition)%20)%20return%20false; CCLog("touchSuccess")%20%20; m_state%20=%20kPaddleStateGrabbed; setSelect(true); if%20(m_selectCallback) { m_selectCallback(m_terminal,%20this); } //sitChair(); return%20true;}void%20Paddle::ccTouchMoved(CCTouch*%20touch,%20CCEvent*%20event){ //%20If%20it%20weren't%20for%20the%20TouchDispatcher,%20you%20would%20need%20to%20keep%20a%20reference //%20to%20the%20touch%20from%20touchBegan%20and%20check%20that%20the%20current%20touch%20is%20the%20same //%20as%20that%20one. //%20Actually,%20it%20would%20be%20even%20more%20complicated%20since%20in%20the%20Cocos%20dispatcher //%20you%20get%20CCSets%20instead%20of%201%20UITouch,%20so%20you'd%20need%20to%20loop%20through%20the%20set //%20in%20each%20touchXXX%20method. CCAssert(m_state%20==%20kPaddleStateGrabbed,%20"Paddle%20-%20Unexpected%20state!");%20%20%20%20 //%20CCPoint%20touchPoint%20=%20touch->getLocation(); //setPosition(%20ccp(touchPoint.x,%20getPosition().y)%20);}CCObject*%20Paddle::copyWithZone(CCZone%20*pZone){ this->retain(); return%20this;}void%20Paddle::ccTouchEnded(CCTouch*%20touch,%20CCEvent*%20event){ CCAssert(m_state%20==%20kPaddleStateGrabbed,%20"Paddle%20-%20Unexpected%20state!");%20%20%20%20 m_state%20=%20kPaddleStateUngrabbed;}%20void%20Paddle::touchDelegateRetain(){ this->retain();}void%20Paddle::touchDelegateRelease(){ this->release();}void%20Paddle::setSelect(bool%20isSelect){ CCArray*%本文来源gao($daima.com搞@代@#码8网^20_array%20=%20this->getChildren(); CCObject%20*_obj; m_isSelect%20=%20isSelect; CCARRAY_FOREACH(_array,%20_obj%20) { CCSprite*%20_sp%20=%20(CCSprite%20*)_obj; if%20(isSelect) { _sp->setColor(ccRED); } else { _sp->setColor(ccWHITE); } }}void%20Paddle::setOpacity(%20GLubyte%20opacity%20){ CCArray*%20_array%20=%20this->getChildren(); CCObject%20*_obj; CCARRAY_FOREACH(_array,%20_obj%20) { CCSprite*%20_sp%20=%20(CCSprite%20*)_obj; _sp->setOpacity(opacity); }}void%20Paddle::sitChair(){ switch%20(m_type) { case%20NONE_TYPE: break; case%20CHAIR_LEFT: { m_playerSprite%20=%20CCSprite::create(g_chair_left_player); m_playerSprite->setAnchorPoint(CCPoint()); m_playerSprite->setPosition(CCPoint(-8,-15)); this->addChild(m_playerSprite,%20100); m_chairPartSprite=%20CCSprite::create(g_chair_left_part); m_chairPartSprite->setAnchorPoint(CCPoint()); m_chairPartSprite->setPosition(CCPoint(-15,-5)); this->addChild(m_chairPartSprite,%20100); break; } case%20CHAIR_FRON: break; case%20CHAIR_RIGHT: break; case%20CHAIR_BACK: { m_playerSprite%20=%20CCSprite::create(g_chair_back_player); m_playerSprite->setAnchorPoint(CCPoint()); m_playerSprite->setPosition(CCPoint(-15,-5)); this->addChild(m_playerSprite); break; } default: break; }}void%20Paddle::standUp(){ if%20(m_playerSprite) { m_playerSprite->removeFromParentAndCleanup(true); m_playerSprite%20=%20NULL; } if%20(m_chairPartSprite) { m_chairPartSprite->removeFromParentAndCleanup(true); m_chairPartSprite%20=%20NULL; }}
////%20%20MathLogic.h//%20%20MapGame////%20%20Created%20by%20TinyUlt%20on%2014/10/11.////#ifndef%20__MapGame__MathLogic__#define%20__MapGame__MathLogic__#include%20#include%20"cocos2d.h"USING_NS_CC;class%20MathLogic{public: //线性方程%20一元二次方法%20求y static%20float%20linearEquationWithOneUnknown_solveYRequiredX(CCPoint%20knownPoint1,%20CCPoint%20knownPoint2,%20float%20x) { float%20_x1%20=%20knownPoint1.x; float%20_y1%20=%20knownPoint1.y; float%20_x2%20=%20knownPoint2.x; float%20_y2%20=%20knownPoint2.y; float%20m_p1%20=%20(_y1%20-_y2)/(_x1-_x2); float%20m_p2%20=%20_y1%20-%20m_p1%20*%20_x1; //%20%20%20%20%20%20%20%20%20float%20m_p1%20=%20(knownPoint1.y%20-knownPoint2.y)/(knownPoint1.x-knownPoint2.x); //%20%20%20%20%20%20%20%20%20float%20m_p2%20=%20knownPoint1.y%20-%20m_p1%20*%20knownPoint1.x; return%20m_p1*%20x%20+%20m_p2; } //线性方程%20一元二次方法%20求x static%20float%20linearEquationWithOneUnknown_solveXRequiredY(CCPoint%20knownPoint1,%20CCPoint%20knownPoint2,%20float%20y) { float%20_x1%20=%20knownPoint1.x; float%20_y1%20=%20knownPoint1.y; float%20_x2%20=%20knownPoint2.x; float%20_y2%20=%20knownPoint2.y; float%20m_p1%20=%20(_y1%20-_y2)/(_x1-_x2); float%20m_p2%20=%20_y1%20-%20m_p1%20*%20_x1; //%20%20%20%20%20%20%20%20%20float%20m_p1%20=%20(knownPoint1.y%20-knownPoint2.y)/(knownPoint1.x-knownPoint2.x); //%20%20%20%20%20%20%20%20%20float%20m_p2%20=%20knownPoint1.y%20-%20m_p1%20*%20knownPoint1.x; return%20(y%20-%20m_p2)/m_p1; } //求点到直线最短路径长度 static%20float%20linearEquationWithOneUnknown_solveShortLenghtRequiredPoint(CCPoint%20knownPoint1,%20CCPoint%20knownPoint2,%20CCPoint%20point) { if%20((point.x%20==%20knownPoint1.x%20&&%20point.y%20==%20knownPoint1.y)%20||%20(point.x%20==%20knownPoint2.x%20&&%20point.y%20==%20knownPoint2.y)) { return%200; } float%20_x1%20=%20knownPoint1.x; float%20_y1%20=%20knownPoint1.y; float%20_x2%20=%20knownPoint2.x; float%20_y2%20=%20knownPoint2.y; float%20m_p1%20=%20(_y1%20-_y2)/(_x1-_x2); float%20m_p2%20=%20_y1%20-%20m_p1%20*%20_x1; CCPoint%20p1((point.y%20-%20m_p2)/m_p1,%20point.y); CCPoint%20p2(point.x,%20m_p1*%20point.x%20+%20m_p2); float%20offsetY%20=%20abs(%20p2.y%20-%20point.y); float%20offsetX%20=%20abs(p1.x%20-%20point.x); if%20(offsetX%20==%200%20&&%20offsetY%20==%200) { return%200; } return%20offsetX%20*%20offsetY%20/%20calculateLengthRequiredTwoPoint(p1,%20p2); } //计算2点距离 static%20float%20calculateLengthRequiredTwoPoint(CCPoint%20p1,%20CCPoint%20p2) { float%20_offsetX%20=%20abs(%20p1.x%20-%20p2.x); float%20_offsetY%20=abs(%20%20p1.y%20-%20p2.y); return%20sqrt(_offsetX%20*%20_offsetX%20+%20_offsetY%20*%20_offsetY); } //绝对值 static%20float%20abs(float%20value) { return%20value>0?value:-value; }};#endif%20/*%20defined(__MapGame__MathLogic__)%20*/
#ifndef%20__HELLOWORLD_SCENE_H__#define%20__HELLOWORLD_SCENE_H__#include%20"PathSearchInfo.h"#include%20"Player.h"class%20Paddle;class%20HelloWorld%20:%20public%20cocos2d::CCLayer{public: //%20Here's%20a%20difference.%20Method%20'init'%20in%20cocos2d-x%20returns%20bool,%20instead%20of%20returning%20'id'%20in%20cocos2d-iphone virtual%20bool%20init();%20%20 //%20there's%20no%20'id'%20in%20cpp,%20so%20we%20recommend%20returning%20the%20class%20instance%20pointer static%20cocos2d::CCScene*%20scene(); //%20a%20selector%20callback void%20menuCloseCallback(CCObject*%20pSender); //%20implement%20the%20"static%20node()"%20method%20manually CREATE_FUNC(HelloWorld); void%20onEnter(); virtual%20bool%20ccTouchBegan(CCTouch*%20touch,%20CCEvent*%20event); virtual%20void%20ccTouchMoved(CCTouch*%20touch,%20CCEvent*%20event); virtual%20void%20ccTouchEnded(CCTouch*%20touch,%20CCEvent*%20event); void%20drawPath(vector&%20vec);//绘制路径(测试用) void%20update(float%20dt);//跟新大地图(行走时,%20人不动,%20地图跟着人动); void%20selectObjCallback(CCPoint%20point,%20Paddle*%20selectObj);//选择物体回调 void%20moveDone(CCPoint%20point);//移动结束回调public: PathSearchInfo*%20m_pathSearch;//寻路引擎类 CCPoint%20m_orignPoint;//人物的起始点 Player*%20m_player;//人物 Paddle*%20m_currentSelect;//当前选中的物品};#endif%20//%20__HELLOWORLD_SCENE_H__
#include%20"HelloWorldScene.h"#include%20"Paddle.h"#include%20"MathLogic.h"#include%20USING_NS_CC;CCScene*%20HelloWorld::scene(){ //%20'scene'%20is%20an%20autorelease%20object CCScene%20*scene%20=%20CCScene::create(); //%20'layer'%20is%20an%20autorelease%20object HelloWorld%20*layer%20=%20HelloWorld::create(); //%20add%20layer%20as%20a%20child%20to%20scene scene->addChild(layer); //%20return%20the%20scene return%20scene;}//%20on%20"init"%20you%20need%20to%20initialize%20your%20instancevoid%20HelloWorld::onEnter(){ CCDirector*%20pDirector%20=%20CCDirector::sharedDirector(); pDirector->getTouchDispatcher()->addTargetedDelegate(this,%20-1,%20false); CCLayer::onEnter();}bool%20HelloWorld::init(){ ////////////////////////////// //%201.%20super%20init%20first if%20(%20!CCLayer::init()%20) { return%20false; } CCSize%20visibleSize%20=%20CCDirector::sharedDirector()->getVisibleSize(); CCPoint%20origin%20=%20CCDirector::sharedDirector()->getVisibleOrigin(); CCTMXTiledMap*%20_map%20=%20CCTMXTiledMap::create("gameMap.tmx"); _map->setPosition(CCPoint()); this->addChild(_map); m_pathSearch%20=%20new%20PathSearchInfo(_map); std::function%20_fun%20=%20std::bind(&HelloWorld::moveDone,this,std::placeholders::_1); m_pathSearch->setMoveDoneCallback(_fun); std::function<void%20(vector)>%20_funDrawPath%20=%20std::bind(&HelloWorld::drawPath,this,std::placeholders::_1); m_pathSearch->setDrawPathCallback(_funDrawPath); std::function%20_funcSelect%20=%20std::bind(&HelloWorld::selectObjCallback,this,std::placeholders::_1,std::placeholders::_2);%20%20 m_pathSearch->setSelectCallback(_funcSelect); ///////////////////////////// %20 CCMenuItemSprite*%20_menuItemSprite%20=%20CCMenuItemSprite::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//精确的寻 路系统, 需要消耗额外的运算(魔兽争霸级的!)