cocos2d-x大型地图的实现
来源:互联网 发布:mac免费翻墙教程 编辑:程序博客网 时间:2024/05/22 07:46
所谓大型地图,是指类似于pc端沙盒游戏那样的地图。需要加载大量的图片资源。而cocos并不是针对这样的游戏设计(现目前手机端很少有2d的类似游戏)。
笔者最近再开发一款类似《饥荒》的生存类游戏,所以涉及到大型地图的实现,下面来和大家聊一聊我自己的实现方式。
· 首先是底层地图实体的逻辑,要实现物体的碰撞,我使用了方格数组来储存地图的相应信息:
struct MapRect{ LandType landType_ = DRY_LAND; short int positionX_ = 0; short int positionY_ = 0;};
底层的数据结构要越简单越好,因为要大量的使用.
· 然后是地图上面的实体,在我设计的游戏中有entity和land两种,entity是人为定义的碰撞体积,而land是不规则的图片,我用了像素检测来判断它的边缘,并且存入底层的方格数组中:
class VirtualMap{public: VirtualMap(); ~VirtualMap();public://inlitialize map data bool recordData();//将地图数据存入文件 bool loadData();//from xml;to be done bool loadLandIndex();//from Imgs bool loadPlantIndex();//from plant.xml bool setCache();//set Map sprite cachepublic://部分成员部分暴露出来供绘制使用 //map data MapRect _landIndex[401][401];//地图网格的数据 SimpleArray<Land*, MAX_LAND_NUMBER> _land; //entities data Vector<Animals*> _animal; Vector<Plants*> _plants; Vector<Products*> _droppedOutProducts;protected://handle imgs int getAlpha(Point, Image*);//图片上的位置和图片在地图上的位置};
部分函数将数据内容存入本地文件,这样地图加载,例如像素检测功能只需要在游戏第一次启动时执行就行
(SimpleArray是自己设计的数据结构,线程安全的动态数组,此处不表)
· 函数的实现,此处用了rapidxml解析本地的xml文件
#include"VirtualMap.h"VirtualMap::VirtualMap() :_land(NullLand::create()){ for (int i = 0; i < 20; i++) { _land[i] = NullLand::create(); }}VirtualMap::~VirtualMap(){}bool VirtualMap::loadLandIndex(){ //加载地图数据 rapidxml::xml_document<> doc_; rapidxml::file<> docl_(FileUtils::getInstance()->fullPathForFilename("land.xml").c_str()); doc_.parse<0>(docl_.data()); if (!doc_.first_node()) { log("ERROR_LAND_XML_NULL"); return false; } else { rapidxml::xml_node<>* node_root = doc_.first_node("ROOT");//获取根节点 rapidxml::xml_node<>* node_land_first = node_root->first_node("land");//指向第一个元素 int count = 0; while (node_land_first) { auto land = new Land(DRY_LAND); rapidxml::xml_node<>* first_sibling = node_land_first->first_node("landType"); land->_landType = (LandType)atoi(first_sibling->value());//字符串转换int first_sibling = first_sibling->next_sibling("positionX"); land->_imgPosition.x = atoi(first_sibling->value()); first_sibling = first_sibling->next_sibling("positionY"); land->_imgPosition.y = atoi(first_sibling->value()); first_sibling = first_sibling->next_sibling("sprite"); land->_imgName = first_sibling->value(); first_sibling = first_sibling->next_sibling("width"); land->_contentSize.x = atoi(first_sibling->value()); first_sibling = first_sibling->next_sibling("height"); land->_contentSize.y = atoi(first_sibling->value()); //end _land.push(land); count++; node_land_first = node_land_first->next_sibling("land"); //移动指针到下一个节点 } } //加载完毕 //处理像素信息 int count = 0; while (_land[count]->_imgName != NullLand::create()->_imgName) { auto img = new Image; auto path = FileUtils::getInstance()->fullPathForFilename("land_0.png"); img->initWithImageFile(path); int w = _land[count]->_contentSize.x / RECT_SIZE; int h = _land[count]->_contentSize.y / RECT_SIZE; int x = _land[count]->_imgPosition.x / RECT_SIZE; int y = _land[count]->_imgPosition.y / RECT_SIZE; for (int a = 0; a < w; a++) { for (int b = 0; b < h; b++) { if (getAlpha(Point(a*RECT_SIZE, b*RECT_SIZE),img)>0)//>20则为图片非透明内容 { _landIndex[a+x][b+y].landType_ = _land[count]->_landType; } } } count++; } return true;}bool VirtualMap::loadPlantIndex(){ rapidxml::xml_document<> doc_; rapidxml::file<> docl_(FileUtils::getInstance()->fullPathForFilename("plant.xml").c_str()); doc_.parse<0>(docl_.data()); if (!doc_.first_node()) { log("ERROR_LAND_XML_NULL"); return false; } else { rapidxml::xml_node<>* node_root = doc_.first_node("ROOT");//获取根节点 rapidxml::xml_node<>* node_land_first = node_root->first_node("plant");//指向第一个元素 int count = 0; while (node_land_first) { rapidxml::xml_node<>* first_sibling = node_land_first->first_node("plantType"); auto pp = Plants::create((PlantType)atoi(first_sibling->value()));//字符串转换int first_sibling = first_sibling->next_sibling("positionX"); pp->ActiveEntity::getPosition().x = atoi(first_sibling->value())/RECT_SIZE; first_sibling = first_sibling->next_sibling("positionY"); pp->ActiveEntity::getPosition().y = atoi(first_sibling->value()) / RECT_SIZE; _plants.pushBack(pp); count++; node_land_first = node_land_first->next_sibling("plant"); //移动指针到下一个节点 } } return true;}int VirtualMap::getAlpha(Point position,Image* img){ position.x += 5; position.y += 5; unsigned char* imgPixelData_ = img->getData(); int w = img->getWidth(); int h = img->getHeight(); int pa = (((h - position.y) - 1)*w + position.x) * 4 + 3; unsigned int alpha = imgPixelData_[pa]; return alpha;}bool VirtualMap::setCache(){ return true;}
关于像素检测,我做了小小的测试,可以看到地图上的渲染图(CSDN图片上传炸了,伤感,下次补上)
0 0
- cocos2d-x大型地图的实现
- cocos2d-x大型地图实现(续)
- Cocos2d-x大型地图
- 【Cocos2d-x】地图滚动算法的实现
- Cocos2d-x 地图行走的实现2:SPFA算法
- Cocos2d-x 地图行走的实现3:A*算法
- Cocos2d-x 地图行走的实现2:SPFA算法
- Cocos2d-x 地图行走的实现3:A*算法
- Cocos2d-x 地图行走的实现2:SPFA算法
- Cocos2d-x 地图行走的实现3:A* 算法
- [cocos2d-x]地图的应用
- ubuntu Cocos2d-x的tiled地图
- [cocos2d-x]瓦片地图的应用
- cocos2d-x瓦片地图
- 【cocos2d-x 大型ARPG手游研发----地图活起来了】
- 【cocos2d-x 大型ARPG手游研发----地图活起来了】
- cocos2d-x 瓦片地图的黑线及地图抖动解决方案
- cocos2d-x 瓦片地图的黑线及地图抖动解决方案
- heap
- iOS-PCH File的快速导入方法和使用
- 关于iOS在向服务器上传数据时
- ROWNUMBER() OVER( PARTITION BY COL1 ORDER BY COL2)用法
- 图书api 查询图书内容
- cocos2d-x大型地图的实现
- vim 自动补全插件 for nodejs
- 外排序(大数据文件排序)
- js数组删除元素
- java 拦截器、过滤器、监听器
- MYSQL 优化
- awk 初学02
- CSS美化上传按钮并获取上传文件路径
- autolayout