cocos2d-x 中 TileMap(块地图 45度视角)的一些问题
2013-07-06 10:37
507 查看
本文采用的cocos2d-x版本是2.1.14
首先,推荐工具tiled,下载不到的朋友可以加我QQ索要安装包。
cocos中对块地图提供了几种不同的类,这里我推荐使用的是CCTMXTiledMap,理由如下:
1,支持平视角 和 45度视角
2,支持多层地图
3,支持地图局部透过(某层某块可以为空)
4,地图编辑工具(tiled)较为方便
下面介绍关于CCTMXTiledMap的用法和技巧:
Features:
- Each tile will be treated as an CCSprite
- The sprites are created on demand. They will be created only when you call "layer->tileAt(position)"
- Each tile can be rotated / moved / scaled / tinted / "opaqued", since each tile is a CCSprite
- Tiles can be added/removed in runtime
- The z-order of the tiles can be modified in runtime
- Each tile has an anchorPoint of (0,0)
- The anchorPoint of the TMXTileMap is (0,0)
- The TMX layers will be added as a child
- The TMX layers will be aliased by default
- The tileset image will be loaded using the CCTextureCache
- Each tile will have a unique tag
- Each tile will have a unique z value. top-left: z=1, bottom-right: z=max z
- Each object group will be treated as an CCMutableArray
- Object class which will contain all the properties in a dictionary
- Properties can be assigned to the Map, Layer, Object Group, and Object
这是头文件中给出的说明,不懂英文的同学自己谷歌翻译。
首先,从头文件的声明
/** the map's size property measured in tiles */
CC_SYNTHESIZE_PASS_BY_REF(CCSize, m_tMapSize, MapSize);
/** the tiles's size property measured in pixels */
CC_SYNTHESIZE_PASS_BY_REF(CCSize, m_tTileSize, TileSize);
两行我们可以知道,可以通过MapSize()来获得地图块的行数和列数
可以通过TileSize()来获得每一块的像素宽和像素高
当然,因为CCTMXTiledMap本身继承自CCNode,所以CCNode自身的Size属性和Postion属性CCTMXTiledMap也是有的。
其次,从说明中,我们可以得知CCTMXTiledMap是由多个CCTMXLayer构成的,我们可以通过CCTMXLayer* layerNamed(const char *layerName)来得到Layer的指针。
关于LayerName,一般是在编辑tmx文件(地图文件)时编辑的,如果tmx文件不是你自己编辑的,可以通过写字板打开tmx文件,在
"<layer name="LayerOne" width="50" height="50">"一行看到层的名字。
在CCTMXLayer中,我们可以通过tileAt(position)来获得每个块的指针,并且将这个块作为CCSprite来操作。
注意:postion的起始坐标(0,0)是地图的左上角(45度地图是正上方角)
也可以通过positionAt()来获得某块地图在大地图上的坐标(注意:锚点是(0,0))
在实际使用中,提问最多的问题 是在45度坐标系下 如何将 触摸点 换算成 地图块坐标(如何知道触摸了哪个地图块)
这里我给出一个坐标变换函数,仅供大家参考:
//将屏幕触摸点换算成 Map块坐标(45度视角地图)
bool CIsoMapLayer::GetTilePosFromScreenPos( const CCPoint ptTouchPoint,CCPoint &ptTilePos )
{
do
{
CCTMXTiledMap* pIOSMap = dynamic_cast<CCTMXTiledMap*>(getChildByTag(enTagMap));
CC_BREAK_IF(pIOSMap==NULL);
//数据校验
CC_BREAK_IF(pIOSMap->getMapSize().width==0||pIOSMap->getMapSize().height==0);
//将屏幕坐标 转换成 Map节点 内坐标
CCPoint ptMapPoint = pIOSMap->convertToNodeSpace(ptTouchPoint);
CCSize sizeMap = pIOSMap->getMapSize();
CCSize sizeTile = pIOSMap->getTileSize();
CCSize sizeNode = pIOSMap->getContentSize();
float fTileSin = GetSinFromMap(pIOSMap);//计算Sin角,请用户自行编写
float fTileCos = GetCosFromMap(pIOSMap);//计算Cos角,请用户自行编写
float fTileTan = sizeTile.height/sizeTile.width;
CC_BREAK_IF(fTileSin==0||fTileCos==0);
//地图块在新坐标系下大小
float fTileWidth = sizeTile.width*0.5f/fTileCos;
float fTileHeight = sizeTile.height*0.5f/fTileSin;//值应该与Weight相同,因为理论上还是方块的
//地图总大小(新坐标系下)
float fMapTotalWidth =fTileWidth*sizeMap.width;
float fMapTotalHeight =fTileHeight*sizeMap.height;//地图总体Size不一定是方形的
//坐标系变换公式
float fMapPosX = (ptMapPoint.x-(ptMapPoint.y-sizeNode.height*0.5f)/fTileTan)*0.5f/fTileCos;
int nXPos = (int)(fMapPosX/fTileWidth);
float fMapPosY = (ptMapPoint.y-sizeNode.height*0.5f)*0.5f/fTileSin+ptMapPoint.x*0.5f/fTileCos;
int nYPos =(int)(fMapPosY/fTileHeight);
//检查是否点击在地图上
if(nYPos<0||nXPos<0)return false;
if(nYPos>=sizeMap.height||nXPos>=sizeMap.width)return false;
//得到地图块坐标
ptTilePos = ccp(nXPos,pIOSMap->getMapSize().height-1-nYPos);
return true;
} while (false);
return false;
}
本人常年承接各类cocos2d-x培训 技术外包 架构指导等工作
QQ:2813610155
Tel:18640244143
首先,推荐工具tiled,下载不到的朋友可以加我QQ索要安装包。
cocos中对块地图提供了几种不同的类,这里我推荐使用的是CCTMXTiledMap,理由如下:
1,支持平视角 和 45度视角
2,支持多层地图
3,支持地图局部透过(某层某块可以为空)
4,地图编辑工具(tiled)较为方便
下面介绍关于CCTMXTiledMap的用法和技巧:
Features:
- Each tile will be treated as an CCSprite
- The sprites are created on demand. They will be created only when you call "layer->tileAt(position)"
- Each tile can be rotated / moved / scaled / tinted / "opaqued", since each tile is a CCSprite
- Tiles can be added/removed in runtime
- The z-order of the tiles can be modified in runtime
- Each tile has an anchorPoint of (0,0)
- The anchorPoint of the TMXTileMap is (0,0)
- The TMX layers will be added as a child
- The TMX layers will be aliased by default
- The tileset image will be loaded using the CCTextureCache
- Each tile will have a unique tag
- Each tile will have a unique z value. top-left: z=1, bottom-right: z=max z
- Each object group will be treated as an CCMutableArray
- Object class which will contain all the properties in a dictionary
- Properties can be assigned to the Map, Layer, Object Group, and Object
这是头文件中给出的说明,不懂英文的同学自己谷歌翻译。
首先,从头文件的声明
/** the map's size property measured in tiles */
CC_SYNTHESIZE_PASS_BY_REF(CCSize, m_tMapSize, MapSize);
/** the tiles's size property measured in pixels */
CC_SYNTHESIZE_PASS_BY_REF(CCSize, m_tTileSize, TileSize);
两行我们可以知道,可以通过MapSize()来获得地图块的行数和列数
可以通过TileSize()来获得每一块的像素宽和像素高
当然,因为CCTMXTiledMap本身继承自CCNode,所以CCNode自身的Size属性和Postion属性CCTMXTiledMap也是有的。
其次,从说明中,我们可以得知CCTMXTiledMap是由多个CCTMXLayer构成的,我们可以通过CCTMXLayer* layerNamed(const char *layerName)来得到Layer的指针。
关于LayerName,一般是在编辑tmx文件(地图文件)时编辑的,如果tmx文件不是你自己编辑的,可以通过写字板打开tmx文件,在
"<layer name="LayerOne" width="50" height="50">"一行看到层的名字。
在CCTMXLayer中,我们可以通过tileAt(position)来获得每个块的指针,并且将这个块作为CCSprite来操作。
注意:postion的起始坐标(0,0)是地图的左上角(45度地图是正上方角)
也可以通过positionAt()来获得某块地图在大地图上的坐标(注意:锚点是(0,0))
在实际使用中,提问最多的问题 是在45度坐标系下 如何将 触摸点 换算成 地图块坐标(如何知道触摸了哪个地图块)
这里我给出一个坐标变换函数,仅供大家参考:
//将屏幕触摸点换算成 Map块坐标(45度视角地图)
bool CIsoMapLayer::GetTilePosFromScreenPos( const CCPoint ptTouchPoint,CCPoint &ptTilePos )
{
do
{
CCTMXTiledMap* pIOSMap = dynamic_cast<CCTMXTiledMap*>(getChildByTag(enTagMap));
CC_BREAK_IF(pIOSMap==NULL);
//数据校验
CC_BREAK_IF(pIOSMap->getMapSize().width==0||pIOSMap->getMapSize().height==0);
//将屏幕坐标 转换成 Map节点 内坐标
CCPoint ptMapPoint = pIOSMap->convertToNodeSpace(ptTouchPoint);
CCSize sizeMap = pIOSMap->getMapSize();
CCSize sizeTile = pIOSMap->getTileSize();
CCSize sizeNode = pIOSMap->getContentSize();
float fTileSin = GetSinFromMap(pIOSMap);//计算Sin角,请用户自行编写
float fTileCos = GetCosFromMap(pIOSMap);//计算Cos角,请用户自行编写
float fTileTan = sizeTile.height/sizeTile.width;
CC_BREAK_IF(fTileSin==0||fTileCos==0);
//地图块在新坐标系下大小
float fTileWidth = sizeTile.width*0.5f/fTileCos;
float fTileHeight = sizeTile.height*0.5f/fTileSin;//值应该与Weight相同,因为理论上还是方块的
//地图总大小(新坐标系下)
float fMapTotalWidth =fTileWidth*sizeMap.width;
float fMapTotalHeight =fTileHeight*sizeMap.height;//地图总体Size不一定是方形的
//坐标系变换公式
float fMapPosX = (ptMapPoint.x-(ptMapPoint.y-sizeNode.height*0.5f)/fTileTan)*0.5f/fTileCos;
int nXPos = (int)(fMapPosX/fTileWidth);
float fMapPosY = (ptMapPoint.y-sizeNode.height*0.5f)*0.5f/fTileSin+ptMapPoint.x*0.5f/fTileCos;
int nYPos =(int)(fMapPosY/fTileHeight);
//检查是否点击在地图上
if(nYPos<0||nXPos<0)return false;
if(nYPos>=sizeMap.height||nXPos>=sizeMap.width)return false;
//得到地图块坐标
ptTilePos = ccp(nXPos,pIOSMap->getMapSize().height-1-nYPos);
return true;
} while (false);
return false;
}
本人常年承接各类cocos2d-x培训 技术外包 架构指导等工作
QQ:2813610155
Tel:18640244143
相关文章推荐
- cocos2d-x 学习笔记之Tiled Map地图使用时的一些问题
- 45度地图遮挡问题解决方案(cocos2d-x)
- cocos2d-x开发中使用tilemap(斜45度)遇到的问题
- 45度地图遮挡问题解决方案(cocos2d-x)
- cocos2d-x 移植到android中编译的一些问题:fatal error: Box2D/Box2D.h: No such file or directory"
- Cocos2D瓦块地图高清屏(retina)显示比例问题的解决
- cocos2d-x使用CCControlButton的一些问题
- 视角来分析 腾讯 微信访客系统的一些问题 (二 )end
- 最近做了个地图软件,写一些经验和心得,以及一些问题
- Cocos2d-x项目总结中的一些遇到的问题
- Cocos2D瓦块地图高清屏(retina)显示比例问题的解决
- cocos2d-x中讲解TileMap地图编辑器的高级用法(一)
- Cocos2d-x项目过程中遇到的一些问题总结
- cocos2d-x中讲解TileMap地图编辑器的高级用法(对象层部分)
- cocos2d-x游戏开发的一些问题
- cocos2d-x 2.2.2 环境配置和创建工程的一些问题
- echarts地图制作的一些问题总结
- cocos2d-x中讲解TileMap地图编辑器的高级用法(对象层部分)
- Cocos2d-x 3.0 Android修改APK名、更改图标、修改屏幕方向、修改版本号,一些需要注意的问题
- cocos2d-x中讲解TileMap地图编辑器的高级用法(二)