2016-11-18 43 views
1

我尝试加载对象TMX文件是这样的:在我的TMX文件的cocos2d-X - ValueMap从TMX返回错误值文件

 // add player 
 
    TMXObjectGroup *objectGroup = _tileMap->getObjectGroup("objects"); 
 
    CCASSERT(NULL != objectGroup, "'objects' objectGroup not find !"); 
 

 
    if(objectGroup == NULL){ 
 
    \t return false; 
 
    } 
 

 
    ValueMap spawnPoint = objectGroup->getObject("SpawnPoint"); 
 
    CCASSERT(!spawnPoint.empty(), "SpawnPoint not find !"); 
 

 
    cocos2d::log("----> Nom : %s", spawnPoint["name"].asString().c_str()); 
 

 
    int id1sP = spawnPoint["id"].asInt(); 
 
    int x = spawnPoint["x"].asInt(); 
 
    int y = spawnPoint["y"].asInt(); 
 
    cocos2d::log("----> spawnPoint[] id(%i)->(%i,%i)",id1sP,x,y); 
 

 
    int id2sP = spawnPoint.at("id").asInt(); 
 
    int x2 = spawnPoint.at("x").asInt(); 
 
    int y2 = spawnPoint.at("y").asInt(); 
 
    cocos2d::log("----> spawnPoint.at() id(%i)->(%i,%i)",id2sP,x2,y2);

,我有这样的价值观:

<objectgroup name="objects"> 
 
    <object id="1" name="SpawnPoint" x="32" y="608" width="32" height="32"/> 
 
</objectgroup>

和在我的日志结果,我有这样的:

Result

我已经尝试asString(),asFloat()转换......而且不明白为什么我没有32和608的结果。我有14和179!

有人可以帮助我吗? 此致敬礼。

回答

0

像这个帖子似乎不是如此令人兴奋,我张贴你我的来源和我试图解决它的原因。首先,我想在翻译的cocos2d-x 2.13这个项目:

Cocos2D-X Tile Map Tutorial: Part1

HelloWorldScene.cpp

#include "HelloWorldScene.h" 
 
#include "SimpleAudioEngine.h" 
 

 
USING_NS_CC; 
 

 
Scene* HelloWorld::createScene() 
 
{ 
 
    // 'scene' is an autorelease object 
 
    auto scene = Scene::create(); 
 
    
 
    // 'layer' is an autorelease object 
 
    auto layer = HelloWorld::create(); 
 

 
    // add layer as a child to scene 
 
    scene->addChild(layer); 
 

 
    // return the scene 
 
    return scene; 
 
} 
 

 
// on "init" you need to initialize your instance 
 
bool HelloWorld::init() 
 
{ 
 
    ////////////////////////////// 
 
    // 1. super init first 
 
    if (!Layer::init()) 
 
    { 
 
     return false; 
 
    } 
 
    
 
    auto visibleSize = Director::getInstance()->getVisibleSize(); 
 
    Vec2 origin = Director::getInstance()->getVisibleOrigin(); 
 

 
    ///////////////////////////// 
 
    // 1. add a menu item with "X" image, which is clicked to quit the program 
 
    // you may modify it. 
 

 
    // add a "close" icon to exit the progress. it's an autorelease object 
 
    auto closeItem = MenuItemImage::create(
 
              "CloseNormal.png", 
 
              "CloseSelected.png", 
 
              CC_CALLBACK_1(HelloWorld::menuCloseCallback, this)); 
 

 
    closeItem->setPosition(Vec2(origin.x + visibleSize.width - closeItem->getContentSize().width/2 , 
 
           origin.y + closeItem->getContentSize().height/2)); 
 

 
    // create menu, it's an autorelease object 
 
    auto menu = Menu::create(closeItem, NULL); 
 
    menu->setPosition(Vec2::ZERO); 
 
    this->addChild(menu, 1); 
 

 
    ///////////////////////////// 
 
    // 3. add map 
 
    std::string file = "medfan.tmx"; 
 
    auto str = String::createWithContentsOfFile(FileUtils::getInstance()->fullPathForFilename(file.c_str()).c_str()); 
 
    _tileMap = TMXTiledMap::createWithXML(str->getCString(),""); 
 
    _background = _tileMap->layerNamed("background"); 
 
    addChild(_tileMap, 0); 
 

 
    ///////////////////////////// 
 
    // 4. add player 
 
    TMXObjectGroup *objectGroup = _tileMap->getObjectGroup("objects"); 
 
    CCASSERT(NULL != objectGroup, "'objects' objectGroup not find !"); 
 

 
    if(objectGroup == NULL){ 
 
    \t return false; 
 
    } 
 

 
    ValueMap spawnPoint = objectGroup->getObject("SpawnPoint"); 
 
    CCASSERT(!spawnPoint.empty(), "SpawnPoint not find !"); 
 

 
    cocos2d::log("----> Name : %s", spawnPoint["name"].asString().c_str()); 
 

 

 
    int idsP = spawnPoint["id"].asInt(); 
 
    int x = spawnPoint["x"].asInt(); 
 
    int y = spawnPoint["y"].asInt(); 
 
    cocos2d::log("----> spawnPoint[x,y] id(%i)->(%i,%i)",idsP,x,y); 
 
    int id2sP = spawnPoint.at("id").asInt(); 
 
    int x2 = spawnPoint.at("x").asInt(); 
 
    int y2 = spawnPoint.at("y").asInt(); 
 
    cocos2d::log("----> spawnPoint.at(x,y) id(%i)->(%i,%i)",id2sP,x2,y2); 
 

 
    auto& objects = objectGroup->getObjects(); 
 
    for (auto &obj : objects) { 
 
     auto &properties = obj.asValueMap(); 
 
     cocos2d::log("------> properties[x,y] = %f,%f",properties["x"].asFloat(), properties["y"].asFloat()); 
 
    } 
 

 
    _player = new Sprite(); 
 
    _player->initWithFile("Player.png"); 
 
    _player->setPosition(Vec2(x,y)); 
 

 
    this->addChild(_player); 
 
    this->setViewPointCenter(_player->getPosition()); 
 

 
    ///////////////////// 
 
    // 5. Touch 
 
    this->setTouchEnabled(true); 
 

 
    auto eventListener = EventListenerTouchOneByOne::create(); 
 
    eventListener->onTouchBegan = CC_CALLBACK_2(HelloWorld::onTouchBegan, this); 
 
    eventListener->onTouchEnded = CC_CALLBACK_2(HelloWorld::onTouchEnded, this); 
 
    this->getEventDispatcher()->addEventListenerWithSceneGraphPriority(eventListener, this); 
 

 
    ///////////////////// 
 
    // 6. collisions 
 
    _meta = _tileMap->layerNamed("meta"); 
 
    _meta->setVisible(false); 
 

 
    return true; 
 
} 
 

 
bool HelloWorld::onTouchBegan(Touch *touch, Event *event) 
 
{ 
 
\t return true; 
 
} 
 

 
void HelloWorld::onTouchEnded(Touch *touch, Event *event){ 
 

 
\t auto actionTo1 = RotateTo::create(0, 0, 180); 
 
\t auto actionTo2 = RotateTo::create(0, 0, 0); 
 

 
\t Point touchLocation = touch->getLocationInView(); 
 
\t touchLocation = Director::sharedDirector()->convertToGL(touchLocation); 
 
\t touchLocation = this->convertToNodeSpace(touchLocation); 
 

 
\t Point playerPos = _player->getPosition(); 
 
\t Point diff = touchLocation - playerPos; 
 

 
\t if (abs(diff.x) > abs(diff.y)) { 
 
\t \t if (diff.x > 0) { 
 
\t \t \t playerPos.x += _tileMap->getTileSize().width; 
 
\t \t \t _player->runAction(actionTo2); 
 
\t \t }else{ 
 
\t \t \t playerPos.x -= _tileMap->getTileSize().width; 
 
\t \t \t _player->runAction(actionTo1); 
 
\t \t } 
 
\t }else{ 
 
\t \t if (diff.y > 0) { 
 
\t \t \t playerPos.y += _tileMap->getTileSize().height; 
 
\t \t }else{ 
 
\t \t \t playerPos.y -= _tileMap->getTileSize().height; 
 
\t \t } 
 
    \t } 
 

 
\t if (playerPos.x <= (_tileMap->getMapSize().width * _tileMap->getMapSize().width) && 
 
\t playerPos.y <= (_tileMap->getMapSize().height * _tileMap->getMapSize().height) && 
 
\t playerPos.y >= 0 && playerPos.x >= 0) 
 
\t { 
 
\t \t this->setPlayerPosition(playerPos); 
 
    \t } 
 

 
\t this->setViewPointCenter(_player->getPosition()); 
 

 
} 
 
void HelloWorld::setPlayerPosition(Point position) 
 
{ 
 

 
    cocos2d::log("setPlayerPosition(position.y=%f", position.y); 
 
    Point tileCoord = this->tileCoordForPosition(position); 
 

 
    //---------------------------------------- 
 
    int tileGid = _meta->tileGIDAt(tileCoord); 
 

 
    if (tileGid) { 
 
    \t cocos2d::log("after if(tileGid)"); 
 
     ValueMap properties = _tileMap->getPropertiesForGID(tileGid).asValueMap(); 
 
     cocos2d::log("properties.size=%i", properties.size()); 
 
     if (properties.size()>0){ 
 
     \t const bool collision = properties.at("Collidable").asBool(); 
 
     \t if (collision == true){ 
 
     \t \t cocos2d::log("collision=TRUE"); 
 
     \t }else{ 
 
     \t \t cocos2d::log("collision=FALSE"); 
 
     \t } 
 
     } 
 
     /* ------------------- WHEN COLLISION WILL BE RESOLVED, LAST THING TO DO 
 
     if (properties) { 
 
      collision = properties->valueForKey("Collidable"); 
 
      if (collision && (collision->compare("True") == 0)) { 
 
       return; 
 
      } 
 
     } 
 
     ----------------- */ 
 
    } 
 

 
\t _player->setPosition(position); 
 
} 
 

 
Point HelloWorld::tileCoordForPosition(Point position) 
 
{ 
 
\t int x = position.x/_tileMap->getTileSize().width; 
 
\t int y = ((_tileMap->getMapSize().height * _tileMap->getTileSize().height)- position.y)/_tileMap->getTileSize().height; 
 
\t return Vec2(x,y); 
 
} 
 

 
void HelloWorld::setViewPointCenter(Point position){ 
 

 
\t Size winSize = Director::getInstance()->getWinSize(); 
 

 
\t int x = MAX(position.x, winSize.width/2); 
 
\t int y = MAX(position.y, winSize.height/2); 
 

 
\t x = MIN(x, (_tileMap->getMapSize().width * this->_tileMap->getTileSize().width)-winSize.width/2); 
 
\t y = MIN(y, (_tileMap->getMapSize().height * _tileMap->getTileSize().height)-winSize.height/2); 
 

 
\t Point actualPosition = Vec2(x,y); 
 

 
\t Point centerOfView = Vec2(winSize.width/2, winSize.height/2); 
 
\t //** Point viewPoint = ccpSub(centerOfView, actualPosition); 
 
\t Point viewPoint = centerOfView - actualPosition; 
 
\t this->setPosition(viewPoint); 
 

 
} 
 

 
void HelloWorld::menuCloseCallback(Ref* pSender) 
 
{ 
 
    //Close the cocos2d-x game scene and quit the application 
 
    Director::getInstance()->end(); 
 

 
    #if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS) 
 
    exit(0); 
 
#endif 
 
    
 
    /*To navigate back to native iOS screen(if present) without quitting the application ,do not use Director::getInstance()->end() and exit(0) as given above,instead trigger a custom event created in RootViewController.mm as below*/ 
 
    
 
    //EventCustom customEndEvent("game_scene_close_event"); 
 
    //_eventDispatcher->dispatchEvent(&customEndEvent); 
 
    
 
    
 
}

你会发现在源(类和Ressources)这个地方的邮编:Tile Map - Cocos2d-x Version 19 November 2016

我希望这会给这个问题更多的兴趣。 谢谢。

0

Tiled TMX格式根据左上角原点定义对象坐标。 Cocos2d具有基于左下角原点的OpenGL坐标。

您必须从瓦片层高度减去物体坐标中的Y值。 y = [“height”] - [“y”]

它也可以在瓷砖(而不是像素)坐标上“偏离1”。

参见:https://github.com/bjorn/tiled/issues/386

的cocos2d确实减去从Y上的高度时,它计算瓦片的点的位置(第独立像素)。