游戏地图是游戏过程重要的环节,这里我们使用地图编辑器编辑我们的地图,其中CCTMXTiledMap是我们创建地图时使用的类对象,接下来是地图编辑器的使用,免费下载地址:http://www.mapeditor.org/
地图编辑器
打开下载好的地图编辑器,打开“文件--->新文件”:
打开后d出窗口,只设置地图高度和宽度(即每一行地图的块数),块的大小(根据自己所选地图),其他为默认。
接着选择“地图--->新图块”,d出窗口,选择编辑地图块,点击“浏览”选择。
点击确定后,即可在右下角看到地图块,拖动编辑地图。
这里我们可以建立两个图层,如下图所示,一个图层存放背景,另一个存放障碍物,方便我们在做碰撞检测时使用。
完成点击“文件---->另存为”,即可生成.tmx地图文件。
地图文件的使用
当然上面的地图能生成垂直俯视和45度俯视两种类型的地图,可以根据需要编辑生成相应的地图。
这里需要注意的是,我们编辑的地图坐标和屏幕坐标一致,都是左上角为原点,但是和cocos2d坐标系不一致,所以需要做一定的转换。另外,由于新的Cocos2d引擎引入了屏幕适配,所以在设置坐标的时候,需要注意坐标转换,这个在例子中会表明。
地图文件.tmx的简单使用:
// 读取地图文件auto map = TMXTiledMap::create("TileMap.tmx");addChild(map);
下面是一个简单的具体事例:
创建一个新的项目“HelloMap”,在HelloMap.h:
<span >#ifndef __HELLOMAP_H__#define __HELLOMAP_H__#include "cocos2d.h"#include "Box2D\Box2D.h"#include "SimpleAudioEngine.h"using namespace cocos2d;class HelloMap : public cocos2d::Layer{private: CCTMXTiledMaP* _mapTile; CCSprite* _spriteNPC;public: static cocos2d::Scene* createMapScene(); virtual bool init(); voID mapMenuCallBack(cocos2d::Ref* pSender); CREATE_FUNC(HelloMap);};#endif // !__HELLOMAP_H__</span>
HelloMap.cpp:
#include "HelloMap.h"USING_NS_CC;// 定义地图块的实际大小#define MAPTILESIZE 33*480.00/1024.00// 按键标示(索引)typedef enum _CONTRolTAG{ TAG_UP=100,TAG_DAOW,TAG_left,TAG_RIGHT,TAG_FIRE}CONTRolTAG;Scene* HelloMap::createMapScene(){ auto mapScene = Scene::create(); auto mapLayer = HelloMap::create(); mapScene->addChild(mapLayer); return mapScene;}bool HelloMap::init(){ if (!Layer::init()) { return false; } CCSize s = Director::getInstance()->getWinSize(); // 创建地图块 _mapTile = CCTMXTiledMap::create("ok.tmx"); _mapTile->setposition(Vec2(0,0)); this->addChild(_mapTile); // 添加游戏NPC _spriteNPC = CCSprite::create("NPC.png"); _spriteNPC->setposition(MAPTILESIZE/2,MAPTILESIZE/2); // 将创建的精灵添加到地图中 _mapTile->addChild(_spriteNPC); // 创建菜单按钮,设置回调函数 CcmenuItemFont *upMenuItem = CcmenuItemFont::create("UP",this,menu_selector(HelloMap::mapMenuCallBack)); CcmenuItemFont *downMenuItem = CcmenuItemFont::create("DOWN",menu_selector(HelloMap::mapMenuCallBack)); CcmenuItemFont *leftMenuItem = CcmenuItemFont::create("left",menu_selector(HelloMap::mapMenuCallBack)); CcmenuItemFont *rightmenuItem = CcmenuItemFont::create("RIGHT",menu_selector(HelloMap::mapMenuCallBack)); CcmenuItemFont *fireMenuItem = CcmenuItemFont::create("FIRE",menu_selector(HelloMap::mapMenuCallBack)); // 将菜单项添加到菜单 Ccmenu *menu = Ccmenu::create(upMenuItem,downMenuItem,leftMenuItem,rightmenuItem,fireMenuItem,NulL); menu->setposition(0,0); this->addChild(menu); upMenuItem->setposition(s.wIDth / 2,s.height - 20); downMenuItem->setposition(s.wIDth / 2,20); leftMenuItem->setposition(35,s.height / 2); rightmenuItem->setposition(s.wIDth - 40,s.height / 2); fireMenuItem->setposition(35,s.height - 30); // 设置按键标示(索引) upMenuItem->setTag(TAG_UP); downMenuItem->setTag(TAG_DAOW); leftMenuItem->setTag(TAG_left); rightmenuItem->setTag(TAG_RIGHT); fireMenuItem->setTag(TAG_FIRE); return true;}// 回调函数voID HelloMap::mapMenuCallBack(Ref* pSender){ // 获取菜单项,并获取索引 CcmenuItem *item = (CcmenuItem*)pSender; int tag = item->getTag(); // 获得精灵的当前位置和下一个节点的位置,这里(33.00 * 480.00 / 1024.00)为每块小地图快的实际像素大小 // 由于Y轴方向上地图坐标与Cocos2d坐标相反,需要转换为地图坐标,及左上角为原点 CCPoint spriteCurPos = ccp((int)(_spriteNPC->getpositionX() / (33.00 * 480.00 / 1024.00)),(int)(_mapTile->getMapSize().height - (_spriteNPC->getpositionY() / (33.00 * 480.00 / 1024.00)))); CCPoint spriteNextPos = spriteCurPos; // 根据图层名字获得图层对象,我们编辑地图时设置了两个图层,layer1存放背景,layer2存放障碍物 CCTMXLayer* ly = _mapTile->layernamed("layer2"); // 地图块ID int GID = 0; switch (tag) { case TAG_UP: // 获取地图下一个位置节点,如果节点小于0,说明已经出边界,直接返回 spriteNextPos.y -= 1; //log("%f----!!!!!!!!------------",spriteNextPos.y); if (spriteNextPos.y < 0) return; // 获取下一个节点的ID,如果节点存在则返回 GID = ly->tileGIDAt(spriteNextPos); if (GID) return; // 碰撞检测,当NPC没走到地图中间时,即在边界的时候,只移动精灵 // 判断精灵是否到达边界或者到达Y轴的中心,这里我们屏幕的分辨率为480*320 // 这里由于Cocos2d 3.x对屏幕适配的影响,不同电脑显示的地图块的屏幕分辨率与实际分辨率会有所不同, // 因此我们需要根据电脑的显示情况进行适当的坐标调整 if (_spriteNPC->getpositionY() < 160 || (_mapTile->getContentSize().height - _spriteNPC->getpositionY() < 160 + MAPTILESIZE && _mapTile->getContentSize().height - _spriteNPC->getpositionY() > MAPTILESIZE)) { // 精灵向上移动,以cocos2d坐标系作为判断,Y轴需要加上一个地图块的距离 _spriteNPC->setposition(_spriteNPC->getpositionX(),_spriteNPC->getpositionY() + MAPTILESIZE); } // 当NPC走到地图中间时,移动地图和精灵来代替精灵走动 else if (_mapTile->getContentSize().height - _spriteNPC->getpositionY() > 160 + MAPTILESIZE) { _mapTile->setposition(_mapTile->getpositionX(),_mapTile->getpositionY() - MAPTILESIZE); _spriteNPC->setposition(_spriteNPC->getpositionX(),_spriteNPC->getpositionY() + MAPTILESIZE); } break; case TAG_DAOW: // 获取下一个节点,如果节点大于59,说明已经出边界,直接返回 spriteNextPos.y += 1; if (spriteNextPos.y > _mapTile->getMapSize().height - 1) return; // 获取下一个节点的ID,如果节点存在则返回 GID = ly->tileGIDAt(spriteNextPos); if (GID) return; if ((_spriteNPC->getpositionY() > MAPTILESIZE && _spriteNPC->getpositionY() < 160 + MAPTILESIZE) || (_mapTile->getContentSize().height - _spriteNPC->getpositionY() < 160 && _mapTile->getContentSize().height - _spriteNPC->getpositionY() > 0)) { _spriteNPC->setposition(_spriteNPC->getpositionX(),_spriteNPC->getpositionY() - MAPTILESIZE); } else if (_spriteNPC->getpositionY() < _mapTile->getContentSize().height - 160 && _spriteNPC->getpositionY() > 160 + MAPTILESIZE) { _mapTile->setposition(_mapTile->getpositionX(),_mapTile->getpositionY() + MAPTILESIZE); _spriteNPC->setposition(_spriteNPC->getpositionX(),_spriteNPC->getpositionY() - MAPTILESIZE); } break; case TAG_left: // 获取下一个节点,如果节点小于0,说明已经出边界,直接返回 spriteNextPos.x -= 1; if (spriteNextPos.x < 0) return; // 获取下一个节点的ID,如果节点存在则返回 GID = ly->tileGIDAt(spriteNextPos); if (GID) return; if ((_spriteNPC->getpositionX() > MAPTILESIZE && _spriteNPC->getpositionX() < 240 + MAPTILESIZE) || (_mapTile->getContentSize().wIDth - _spriteNPC->getpositionX() < 240 && _mapTile->getContentSize().wIDth - _spriteNPC->getpositionX() > 0)) { _spriteNPC->setposition(_spriteNPC->getpositionX() - MAPTILESIZE,_spriteNPC->getpositionY()); } else if (_spriteNPC->getpositionX() < _mapTile->getContentSize().wIDth - 240 && _spriteNPC->getpositionX() > 240 + MAPTILESIZE) { _mapTile->setposition(_mapTile->getpositionX() + MAPTILESIZE,_mapTile->getpositionY() ); _spriteNPC->setposition(_spriteNPC->getpositionX() - MAPTILESIZE,_spriteNPC->getpositionY()); } break; case TAG_RIGHT: // 获取下一个节点,如果节点大于59,说明已经出边界,直接返回 spriteNextPos.x += 1; if (spriteNextPos.x > _mapTile->getMapSize().wIDth - 1) return; // 获取下一个节点的ID,如果节点存在则返回 GID = ly->tileGIDAt(spriteNextPos); if (GID) return; if (_spriteNPC->getpositionX() < 240 || (_mapTile->getContentSize().wIDth - _spriteNPC->getpositionX() < 240 - MAPTILESIZE && _mapTile->getContentSize().wIDth - _spriteNPC->getpositionX() > MAPTILESIZE)) { _spriteNPC->setposition(_spriteNPC->getpositionX() + MAPTILESIZE,_spriteNPC->getpositionY()); } else if (_mapTile->getContentSize().wIDth - _spriteNPC->getpositionX() > 240 - MAPTILESIZE) { _mapTile->setposition(_mapTile->getpositionX() - MAPTILESIZE,_mapTile->getpositionY()); _spriteNPC->setposition(_spriteNPC->getpositionX() + MAPTILESIZE,_spriteNPC->getpositionY()); } break; case TAG_FIRE: // 替换地图块 ly->setTileGID(46,spriteCurPos); break; }}
由于文件过大,这里只上传类文件,源码下载:http://download.csdn.net/detail/u013707014/9003805
总结以上是内存溢出为你收集整理的Cocos2d-x学习笔记(九)—— 地图系统(地图编辑器,事件响应)全部内容,希望文章能够帮你解决Cocos2d-x学习笔记(九)—— 地图系统(地图编辑器,事件响应)所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)