Cocos2d-x学习笔记(九)—— 地图系统(地图编辑器,事件响应)

Cocos2d-x学习笔记(九)—— 地图系统(地图编辑器,事件响应),第1张

概述游戏地图是游戏过程重要的环节,这里我们使用地图编辑器编辑我们的地图,其中CCTMXTiledMap是我们创建地图时使用的类对象,接下来是地图编辑器的使用,免费下载地址:http://www.mapeditor.org/ 地图编辑器 打开下载好的地图编辑器,打开“文件--->新文件”: 打开后d出窗口,只设置地图高度和宽度(即每一行地图的块数),块的大小(根据自己所选地图),其他为默认。 接着选择“

游戏地图是游戏过程重要的环节,这里我们使用地图编辑器编辑我们的地图,其中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学习笔记(九)—— 地图系统(地图编辑器,事件响应)所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/1068505.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-26
下一篇 2022-05-26

发表评论

登录后才能评论

评论列表(0条)

保存