Tiled瓦片地图的使用
2016-10-22 15:05
239 查看
Tiled软件使用的注意事项:
1️⃣文件的导入。图层文件的导入不能有中文名字,最好是先把需要的资源文件导入到工程的Resource文件夹中,让后到这个文件夹中导入Tiled软件,进行瓦片地图的绘制。
2️⃣文件的导出。在保存的时候就可以直接保存到工程的Resource文件夹中,随后在工程中添加,即导出成功。导出后可以查看.tmx文件,可以尝试着读懂导出的.tmx文件。
以上步骤完成后就可以在程序中使用瓦片地图了。
// 获得地图层,将其层级设为-1
TMXTiledMap * m_tiled = TMXTiledMap::create(“Tiled1.tmx");
addChild(m_tiled,-1);
//获得图层
TMXLayer * floor = tiled->getLayer("floor");
接着我们要添加英雄对象了,首先要先设置一个对象层,接着为了设置英雄的精灵图片,设置一个矩形区域(“图层”)
TMXObjectGroup
* objects = m_tiled->getObjectGroup("object");
ValueMap
m_player = objects->getObject(“player”);
然后设置一个精灵,用这个对象的坐标来设置精灵的位置
int
x = m_player["x"].asInt();
int
y = m_player["y"].asInt();
auto
hero = Sprite::create("Player.png");
hero->setPosition(x, y);
这时候,精灵已经可以在地图上显示出来了,值得注意的是对象曾与对象之间是Map的键值对的存储形式
这时候需要考虑通过点击来控制英雄的移动了。首先要设置触摸监听,代码略去,在重写的触摸事件中首先要知道点击点的位置是世界坐标系,相对于屏幕的左下角,需要将其转换为节点坐标系的点(相对于layer,因为在layer中的精灵坐标是相对于layer的坐标),通过点击屏幕让英雄瞬移到所点击屏幕的坐标显然是不可行的,我们点击一下让英雄移动一个瓦块的距离,通过点击的位置与英雄的位置差来判断行走的方向。
bool
[b]TiledTest::onTouchBegan(Touch
*touch,
Event
*unused_event){
auto
touchPos = touch->getLocation();
auto
heroPos =
hero->getPosition();
auto
direction = touchPos - heroPos;
if
(std::abs(direction.x)>std::abs(direction.y))
{
if
(direction.x<0)
{//left
heroPos.x
-=
m_tiled->getTileSize().width;
}else{//right[/b]
heroPos.[b]x
+=
m_tiled->getTileSize().width;[/b]
}// 出于方便的考虑将m_tiled设为了成员变量
[b] }else{[/b]
[b]if (directio n.y<0)
{[/b]
[b] heroPos.y
-=
m_tiled->getTileSize().height;
}
else{
heroPos.y
+=
m_tiled->getTileSize().height;
}[/b]
}
[b]hero->setPosition(heroPos);// 出于方便的考虑将hero设为了成员变量[/b]
[b]
return
true;[/b]
由于地图的比较大,需要设置屏幕的适配,类似于前面说到的摄像机类,即让英雄能够走完整个地图,我们写一个名字为setPlayerPosition(Vec2 pos)的函数来完成这一功能。
屏幕中心与地图位置的差值最小是屏幕大小的一半,最大是地图的大小减去屏幕大小的一半,我们选择设置一个在一个void setViewPosition(Vec2 pos)函数中实现这个功能.
void
[b]TiledTest::setLayerPosition(Vec2
pos){
auto
winsize =
Director::getInstance()->getVisibleSize();
int
x,y;//差值(相对距离)
if
(pos.x
> winsize.width/2)
{
x = pos.x;
}else{ x = winsize.width/2;
}
if
(pos.y
> winsize.height/2)
{
y = pos.y;
}else{ y = winsize.height/2;
}
auto
width =
m_tiled->getTileSize().width
*
m_tiled->getMapSize().width-winsize.width/2;
auto
height =
m_tiled->getMapSize().height
*
m_tiled->getTileSize().height-winsize.height/2;
if
(x>width) {
x = width;
}
if
(y>height) {
y = height;
}
auto
layerPos =
Vec2(winsize.width/2,
winsize.height/2)-
Vec2(x, y);[/b]
[b]this[b]->setPosition[/b](layerPos);}[/b]
此时我们应该考虑限制英雄的移动了,对墙体等应设置属性让其无法通过,而对“蔬菜”应该让其吃掉。这时候需要使用Tiled软件添加一个图层,给起一个标记,添加属性与值,在程序中可以得到他,以便做碰撞检测.这个图层即为标记层,专门处理墙的问题。其中首先需要经过一个节点坐标到瓦片坐标的转换,瓦片地图以左上角为原点,每一个瓦片为单位。
Vec2
HelloWorld::getTiledPos(Vec2
pos){
int
x = pos.x/m_tiled->getTileSize().width;
int
y = (m_tiled->getMapSize().height*m_tiled->getTileSize().height
- pos.y)/m_tiled->getTileSize().height;
return Vec2(x, y);}
然后就需要根据属性值来得到墙,做碰撞检测.首先每一个瓦片都有一个唯一的ID值。通过获得ID来判断设置的标记wall是否为true,若不是则不是墙。
void
TiledTest::setPlayerPostion(Vec2
pos){
auto
tiledCoord = this->getTiledPos(pos);
auto
tiledGID = meta->getTileGIDAt(tiledCoord);
if
(tiledGID) {
ValueMap
properties = m_tiled->getPropertiesForGID(tiledGID).asValueMap();
if
(!properties.empty()) {
auto
wall = properties["wall"].asString();
if
(wall=="true") {
log("zhuangqiang");
return;
}
}
}
hero->setPosition(pos);// 若没有撞墙则正常移动
是不是该考虑给水果,蔬菜设置可以被英雄吃掉?这时候需要额外建立一个图层并添上要被吃掉的水果并添加属性,因为需要吃掉水果,水果需要被移除,倘若不新建一个层,删除后会成一个黑洞或报错。
if
(foodwall=="true") {// 在判断撞墙处
food->removeTileAt(Vec2(tiledCoord.x,
tiledCoord.y));}
这时候要添加敌人了void addEnemy(Vec2 pos);
1️⃣文件的导入。图层文件的导入不能有中文名字,最好是先把需要的资源文件导入到工程的Resource文件夹中,让后到这个文件夹中导入Tiled软件,进行瓦片地图的绘制。
2️⃣文件的导出。在保存的时候就可以直接保存到工程的Resource文件夹中,随后在工程中添加,即导出成功。导出后可以查看.tmx文件,可以尝试着读懂导出的.tmx文件。
以上步骤完成后就可以在程序中使用瓦片地图了。
// 获得地图层,将其层级设为-1
TMXTiledMap * m_tiled = TMXTiledMap::create(“Tiled1.tmx");
addChild(m_tiled,-1);
//获得图层
TMXLayer * floor = tiled->getLayer("floor");
接着我们要添加英雄对象了,首先要先设置一个对象层,接着为了设置英雄的精灵图片,设置一个矩形区域(“图层”)
TMXObjectGroup
* objects = m_tiled->getObjectGroup("object");
ValueMap
m_player = objects->getObject(“player”);
然后设置一个精灵,用这个对象的坐标来设置精灵的位置
int
x = m_player["x"].asInt();
int
y = m_player["y"].asInt();
auto
hero = Sprite::create("Player.png");
hero->setPosition(x, y);
这时候,精灵已经可以在地图上显示出来了,值得注意的是对象曾与对象之间是Map的键值对的存储形式
这时候需要考虑通过点击来控制英雄的移动了。首先要设置触摸监听,代码略去,在重写的触摸事件中首先要知道点击点的位置是世界坐标系,相对于屏幕的左下角,需要将其转换为节点坐标系的点(相对于layer,因为在layer中的精灵坐标是相对于layer的坐标),通过点击屏幕让英雄瞬移到所点击屏幕的坐标显然是不可行的,我们点击一下让英雄移动一个瓦块的距离,通过点击的位置与英雄的位置差来判断行走的方向。
bool
[b]TiledTest::onTouchBegan(Touch
*touch,
Event
*unused_event){
auto
touchPos = touch->getLocation();
auto
heroPos =
hero->getPosition();
auto
direction = touchPos - heroPos;
if
(std::abs(direction.x)>std::abs(direction.y))
{
if
(direction.x<0)
{//left
heroPos.x
-=
m_tiled->getTileSize().width;
}else{//right[/b]
heroPos.[b]x
+=
m_tiled->getTileSize().width;[/b]
}// 出于方便的考虑将m_tiled设为了成员变量
[b] }else{[/b]
[b]if (directio n.y<0)
{[/b]
[b] heroPos.y
-=
m_tiled->getTileSize().height;
}
else{
heroPos.y
+=
m_tiled->getTileSize().height;
}[/b]
}
[b]hero->setPosition(heroPos);// 出于方便的考虑将hero设为了成员变量[/b]
[b]
return
true;[/b]
由于地图的比较大,需要设置屏幕的适配,类似于前面说到的摄像机类,即让英雄能够走完整个地图,我们写一个名字为setPlayerPosition(Vec2 pos)的函数来完成这一功能。
屏幕中心与地图位置的差值最小是屏幕大小的一半,最大是地图的大小减去屏幕大小的一半,我们选择设置一个在一个void setViewPosition(Vec2 pos)函数中实现这个功能.
void
[b]TiledTest::setLayerPosition(Vec2
pos){
auto
winsize =
Director::getInstance()->getVisibleSize();
int
x,y;//差值(相对距离)
if
(pos.x
> winsize.width/2)
{
x = pos.x;
}else{ x = winsize.width/2;
}
if
(pos.y
> winsize.height/2)
{
y = pos.y;
}else{ y = winsize.height/2;
}
auto
width =
m_tiled->getTileSize().width
*
m_tiled->getMapSize().width-winsize.width/2;
auto
height =
m_tiled->getMapSize().height
*
m_tiled->getTileSize().height-winsize.height/2;
if
(x>width) {
x = width;
}
if
(y>height) {
y = height;
}
auto
layerPos =
Vec2(winsize.width/2,
winsize.height/2)-
Vec2(x, y);[/b]
[b]this[b]->setPosition[/b](layerPos);}[/b]
此时我们应该考虑限制英雄的移动了,对墙体等应设置属性让其无法通过,而对“蔬菜”应该让其吃掉。这时候需要使用Tiled软件添加一个图层,给起一个标记,添加属性与值,在程序中可以得到他,以便做碰撞检测.这个图层即为标记层,专门处理墙的问题。其中首先需要经过一个节点坐标到瓦片坐标的转换,瓦片地图以左上角为原点,每一个瓦片为单位。
Vec2
HelloWorld::getTiledPos(Vec2
pos){
int
x = pos.x/m_tiled->getTileSize().width;
int
y = (m_tiled->getMapSize().height*m_tiled->getTileSize().height
- pos.y)/m_tiled->getTileSize().height;
return Vec2(x, y);}
然后就需要根据属性值来得到墙,做碰撞检测.首先每一个瓦片都有一个唯一的ID值。通过获得ID来判断设置的标记wall是否为true,若不是则不是墙。
void
TiledTest::setPlayerPostion(Vec2
pos){
auto
tiledCoord = this->getTiledPos(pos);
auto
tiledGID = meta->getTileGIDAt(tiledCoord);
if
(tiledGID) {
ValueMap
properties = m_tiled->getPropertiesForGID(tiledGID).asValueMap();
if
(!properties.empty()) {
auto
wall = properties["wall"].asString();
if
(wall=="true") {
log("zhuangqiang");
return;
}
}
}
hero->setPosition(pos);// 若没有撞墙则正常移动
是不是该考虑给水果,蔬菜设置可以被英雄吃掉?这时候需要额外建立一个图层并添上要被吃掉的水果并添加属性,因为需要吃掉水果,水果需要被移除,倘若不新建一个层,删除后会成一个黑洞或报错。
if
(foodwall=="true") {// 在判断撞墙处
food->removeTileAt(Vec2(tiledCoord.x,
tiledCoord.y));}
这时候要添加敌人了void addEnemy(Vec2 pos);
相关文章推荐
- 【爱上cocos2d-x之十八】Tiled瓦片地图编辑器的基本使用
- 【Cocos2d-X开发学习笔记】第25期:游戏背景之瓦片地图集类(CCTMXTiledMap)的使用
- (译)加入敌人和战斗:如果使用cocos2d制作基于tiled地图的游戏:第三部分
- (译)加入敌人和战斗:如果使用cocos2d制作基于tiled地图的游戏:第三部分
- 【Cocos2d-X开发学习笔记】开发工具之Tiled地图编辑器的使用
- 【Cocosd2d实例教程二】地图编辑器Tiled的安装使用
- andengine游戏引擎实用篇-box2d与瓦片地图的结合使用
- mapwin和Tiled(游戏地图编辑器)使用指南
- 使用瓦片地图
- mapwin和Tiled(手机游戏地图编辑器)使用指南
- (译)碰撞检测和收集物品:如何使用cocos2d制作基于tiled地图的游戏:第二部分
- 使用Tiled地图及利用地图设置坐标
- 如何使用cocos2d制作基于tiled地图的游戏
- 11. 碰撞检测和收集物品:如何使用cocos2d制作基于tiled地图的游戏:第二部分
- [转]mapwin和Tiled(游戏地图编辑器)使用指南
- 使用百度地图离线JavaScript API加载本地瓦片地图
- (译)碰撞检测和收集物品:如何使用cocos2d制作基于tiled地图的游戏:第二部分
- OpenStreetMap初探(八)——制作地图瓦片Kosmos及Maperitive使用
- 使用cocos2d-x显示瓦片地图,发现两个瓦片衔接的地方有黑线,找了一下解决方案:
- (译)碰撞检测和收集物品:如何使用cocos2d制作基于tiled地图的游戏:第二部分