您的位置:首页 > 其它

Tiled 使用总结

2016-07-28 11:58 162 查看
<1>知识点:地图的创建。

第一步:新建--》新文件 (就可以打开一个地图了)。

第二步:地图--》新图块 (这样就可以利用这些图块资源当做砖块来填充图层了)。

第三步:就可以添加:图层、对象层、图像图层了。

第四步:利用图块填充好对应的图层。

第五步:添加对象层。添加过对象层后可用插入矩形等来插入对象,还可以为对象名;切记一个对象层可以容纳很多个对象,可以通过对象层的名字返回对象的信息。

第六步:文件--》另存为(命名一下之后就得到地图了)。

总结:可知,最后 图层和对象层和必不可少的资源图片组成了最后的地图。

当然了,地图的大小什么的就是设计好后依然可以调整,不然就太不灵活了。

<2>知识点:地图长度问题。

Tiled制作的砖块地图过长的时候下面是可以拖动滚动条滚动的,因此完全可以通过滚动看到整个地图的全貌。因此尽管你的超级玛丽地图很长,但是不用担心,你是可以通过滚动看到地图全貌的设计的。

<3>知识点:地图中的图块编号与坐标。

A,图块编号是左上角是(0,0)。而且对象编号是从0开始索引的。

B,坐标依然是从左下角开始的。因此对象的位置是(它距左下角的X位置 * 每个格子X像素, 它距左下角的Y位置 * 每个格子Y像素)

<4>知识点:地图的加载代码实现。

方法1:直接加载地图,并且设置地图层的抗锯齿属性。

_tilemp=CCTMXTiledMap::create("pd_tilemap.tmx");

CCObject*  obj=NULL;

CCARRAY_FOREACH(_tilemp->getChildren(),obj)

{

    CCTMXLayer* _child=(CCTMXLayer*)obj;

    _child->getTexture()->setAliasTexParameters();  //关闭抗锯齿

}

this->addChild(_tilemp);

方法2:通过路径加载(注意一下CCFileUtils的使用)。

string resources = "TileMaps";

string file = resources + "/orthogonal-test1.tmx";

CCString* str = CCString::createWithContentsOfFile(CCFileUtils::sharedFileUtils()->fullPathFromRelativePath(file.c_str()));

//create参数说明:资源文件全路径,资源路径目录

CCTMXTiledMap *map = CCTMXTiledMap::create(str->getCString() ,resources.c_str()); 

<5>知识点:地图的滚动。

void HelloWorld::mapScroll(CCPoint touchPoint)

{

    CCSize winSize=CCDirector::sharedDirector()->getWinSize();

    int x=MAX(touchPoint.x, winSize.width/2);

    int y=MAX(touchPoint.y, winSize.height/2);

    x=MIN(x,(this->m_tiledMap->getMapSize().width*this->m_tiledMap->getTileSize().width)-winSize.width/2);

    y=MIN(y,(this->m_tiledMap->getMapSize().height*this->m_tiledMap->getTileSize().height)-winSize.height/2);

    CCPoint actualPosition=ccp(x,y);

    CCPoint centerOfView=ccp(winSize.width/2,winSize.height/2);

    CCPoint viewPoint=ccpSub(centerOfView,actualPosition);  //v1 - v2 也就是第一个减去第二个

    this->setPosition(viewPoint);

}

<6>知识点:让机器人朝靠近英雄的地方走。

void GameLayer::updateRobots(float dt)

{
int alive=0; //当前活着的机器人的数量
int distanceSQ;
int randomChoice=0;
CCObject* pObject=NULL;
CCARRAY_FOREACH(this->_robots,pObject){
Robot* robot=(Robot*)pObject;
if(robot->_actionState != kActionDead){
alive++;
if(::GetCurTime()>robot->_nextDecisionTime){
distanceSQ=ccpDistanceSQ(robot->getPosition(),this->_hero->getPosition());

if(distanceSQ<=50*50){
robot->_nextDecisionTime=::GetCurTime()+frandom_range(0.1,0.5)*1000;
randomChoice=random_range(0,1);

if(randomChoice==0){   //机器人执行攻击动作
if(this->_hero->getPositionX()>robot->getPositionX()){
robot->setScaleX(1.0f);
}else{
robot->setScaleX(-1.0f);
}

robot->_nextDecisionTime=robot->_nextDecisionTime+frandom_range(0.1,0.5)*2000;

robot->attack();

//检测机器人是否攻击到英雄
if(fabsf(this->_hero->getPositionY()-robot->getPositionY())<10){
if(_hero->_hitBox.actual.intersectsRect(robot->_attackBox.actual)){
_hero->hurtWithDamage(robot->_damage);

if(_hero->_actionState==kActionDead && (((GameScene*)(this->getParent()))->_hudLayer->getActionByTag(537)==NULL)){
this->endGame();
}
}
}
}else{   //执行空闲动作
robot->idle();
}
}else if(distanceSQ <= CCDirector::sharedDirector()->getWinSize().width*CCDirector::sharedDirector()->getWinSize().width){
robot->_nextDecisionTime=::GetCurTime()+frandom_range(0.5,1.0)*1000;
randomChoice=random_range(0,2);

if(randomChoice==0){  //机器人执行行走动作
CCPoint moveDirection=ccpNormalize(ccpSub(_hero->getPosition(),robot->getPosition()));  //求标准化向量

robot->walkWithDirection(moveDirection);
robot->updateDesiredPosition(dt*20);
//robot->setPosition(robot->_desiredPosition);

}else{  //执行空闲动作
robot->idle();
}
}
}
}
}

if(alive==0 && ((GameScene*)(this->getParent()))->_hudLayer->getChildByTag(537)==NULL){
this->endGame();
}

}

<7>限制敌人只能在地图内走动。

CCObject* pObject=NULL;

CCARRAY_FOREACH(this->_robots,pObject){
Robot* robot=(Robot*)pObject;
posx=MIN(this->_tilemp->getMapSize().width*this->_tilemp->getTileSize().width-robot->_centerToSides,MAX(robot->_centerToSides,robot->_desiredPosition.x));
posY=MIN(3*this->_tilemp->getTileSize().height+robot->_centerToBottom,MAX(robot->_centerToBottom,robot->_desiredPosition.y));
robot->setPosition(ccp(posx,posY));
}

<8>Tiled中的碰撞检测。

名词:meta  图元  tile  砖块

变量:

CCTMXTiledMap* m_tiledMap;  //地图

CCSprite* wangYijIe;  //英雄王义杰

CCTMXLayer* m_meta;   //障碍物层(英雄不可穿越)

A,第一步:将该碰撞层设置为不可见(虽然不可见,但是还是可以获取其砖块)  

m_meta = m_tiledMap->layerNamed("Meta");

m_meta->setVisible(false);

B,以人物不能穿越障碍物为例,人物行走代码如下。

//返回游戏中某点对应的地图中砖块的坐标。

CCPoint HelloWorld::tileCoordForPosition(CCPoint position)

{

    int x = position.x / m_tiledMap->getTileSize().width;

    int y = (m_tiledMap->getContentSize().height - position.y) / m_tiledMap->getTileSize().height;

    return CCPointMake(x, y);

}

//

void HelloWorld::setPlayerPosition(CCPoint position)

{

    //当没有障碍物时,英雄行走

    CCPoint heroPoint = wangYijIe->getPosition();  //

    int x, y;

    if(position.x > heroPoint.x)

       x = heroPoint.x + 5;

    else

       x = heroPoint.x - 5;

    if (position.y > heroPoint.y)
y = heroPoint.y + 5;

    else

        y = heroPoint.y - 5;

    CCPoint tileCoord = this->tileCoordForPosition(ccp(x, y));

    int tileGid = m_meta->tileGIDAt(tileCoord);

    if(tileGid)   //不为0说明那边有不可穿越的砖块,因此直接返回

(如果这里有砖块,那么就是碰撞了)
return;
 

    wangYijIe->setPosition(ccp(x, y));

}

<9>知识点:熟练对Tiled地图的一些操作。

A,根据名字获得层对象

CCTMXLayer* layer = map->layerNamed("trees");

B,根据精灵在层中的位置可以获得对应的精灵。

m_tamara = layer->tileAt(ccp(0,11));

C,移除(x, y)位置的精灵。

方法1:

CCSprite* sprite = layer->tileAt( ccp(x,y) );

layer->removeChild(sprite, true); 

方法2:

layer->removeTileAt( ccp(x,y) );

D,根据群组名获得对象群组,并且遍历群组的元素输出其坐标。

CCTMXObjectGroup* group = m_tiledMap->objectGroupNamed("Hero");

CCArray* heroArrayDic = group->getObjects();
 

CCObject* dicObj;

CCARRAY_FOREACH(heroArrayDic, dicObj)

{

    CCDictionary* dic = (CCDictionary*)dicObj;
 

    float x = dic->valueForKey("x")->floatValue();
 

    float y = dic->valueForKey("y")->floatValue();
 

    CCLog("%f,  %f", x, y);   //显而易见,可以通过该x,y坐标来初始化比如金币等精灵。

}

特例:当对象层只有一个英雄对象时,可以获取到这个英雄。

CCTMXObjectGroup* group = m_tiledMap->objectGroupNamed("Hero");

CCDictionary* dic = (CCDictionary*)group->getObjects()->objectAtIndex(0);

float x = dic->valueForKey("x")->floatValue();

float y = dic->valueForKey("y")->floatValue();

wangYijIe = CCSprite::create("WangYiJie.jpg");   //显而易见,可以通过该x,y坐标来初                                                                                始化比如金币等精灵
wangYijIe->setPosition(ccp(x, y));

addChild(wangYijIe);

<10>知识点:熟悉几个函数。

A,getMapSize

CCLog("%f,  %f", m_tiledMap->getMapSize().width, m_tiledMap->getMapSize().height);   

//30  12  (也就是横向和竖向的砖块个数)

B, getTileSize  

CCLog("%f,  %f", m_tiledMap->getTileSize().width, m_tiledMap->getTileSize().height); 

//40  40  (也就是每个砖块的像素 横和竖都是40个像素)

C,getContentSize

CCLog("%f,  %f", m_tiledMap->getContentSize().width, m_tiledMap->getContentSize().height);  

//1200  480  (地图的大小  也就是宽和高)

总结:

这个我举得例子虽然有点特殊(地图大小恰好和屏幕一般大),但是我们已经可以得出下面的结论:

地图的宽度为:m_tiledMap->getMapSize().width * m_tiledMap->getTileSize().width

地图的高度为:m_tiledMap->getMapSize().height * m_tiledMap->getTileSize().height

或者这样写:

地图的宽度为:m_tiledMap->getContentSize().width()

地图的高度为:m_tiledMap->getContentSize().height()

<11>知识点:熟悉对象的一些属性。

将.tmx文件的地图用notepad++打开,发现其实所谓的.tmx Tiled文件本质是一个XML文件。

对于对象层中的对象,那么它就自己本身含有坐标x,y,width,height等属性。我们可以轻松

通过这些属性来获取对象的位置和宽高等信息。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: