Ogre3d具有唯一的节点名称错误

时间:2017-04-06 18:11:44

标签: c++ duplicates nodes ogre3d

我正在为我的pcg游戏做城市一代。我有一个for循环,让3个城市在随机位置,我指定parentIteration来获取城市的“id”,并在我建造建筑物的for循环中做同样的事情

for (int i = 0; i < 3; i++)
{
    parentIteration = i;
    std::srand(i);
    _rootNode = GameManager::getSingletonPtr()->getSceneManager()->getRootSceneNode();

    _cityNode = _rootNode->createChildSceneNode("cityNode " + parentIteration);
    generateCity(std::rand() % 10000 + 10, std::rand() % 10000 + 10, std::rand() % 11 +1);
}

建筑

for (int i = 0; i < _numberOfBuildings; i++)
    {
        childIteration = i;
        printf(" parent  %d and child %d \n", parentIteration, childIteration);
        Ogre::SceneNode* buildingNode  = _cityNode->createChildSceneNode("citybuildingNode"+childIteration+parentIteration );
}

然而,当我尝试启动游戏时,它将在创建第二个城市时崩溃。说它已经有一个类似于它试图写的名字。然而我的printf清楚地表明,那时的数字都是独一无二的。有谁知道如何解决这个问题? (添加图片以证明输出)

enter image description here

1 个答案:

答案 0 :(得分:2)

错误消息中的“itybuildingNode”表示

"citybuildingNode"+childIteration+parentIteration

没有按照你想要的方式工作。

这是因为有几件事情对你不利:

  1. “citybuildingNode”是一个String Literal,而不是一个字符串对象。它只是一行中由空字符终止的一串字符,表示为const char *,指向该字符数组的指针。它是低级伏都教,你可以做一些字符串类的东西。 For more information see String Literals

  2. 因为它不是一个字符串对象,所以你不能拉出任何常见的字符串对象技巧,比如与+连接并与==进行比较。但是因为它是一个指针,编译器将+解释为尝试执行指针算法并引用数组中的另一个位置。它编译,但请注意它如何将“citybuildingNode”变成“itybuildingNode”。哎呀。

  3. 这看起来像是:

    const char* temp = "citybuildingNode"
    _cityNode->createChildSceneNode(temp + childIteration + parentIteration);
    

    解析为

    const char* temp = "citybuildingNode"
    _cityNode->createChildSceneNode(&temp[childIteration + parentIteration]);
    
    1. 即使它是字符串对象,C ++标准字符串对象std::string也不允许您向字符串添加数字。它只会将字符串组合在一起以构建更大的字符串。要向std::string添加号码,您必须将号码转换为std::stringstd::to_string可以为您提供帮助,但std::stringstream
    2. 有一种更清晰的方式

      例如:

      std::stringstream nodename("citybuildingNode"); 
      // builds a string stream around the string literal
      nodename << childIteration << parentIteration;
      // writes the numbers into the stream the same way `cin << number;` would
      // turning the number into a string for you
      Ogre::SceneNode* buildingNode  = _cityNode->createChildSceneNode(nodename.str());
      // gets the assembled string from the stringstream 
      // null-terminated string like ogre expects
      

      这可以帮助您从正确的方向开始,但仍允许子1和父10(“citybuildingNode110”)和子11以及父0(也称为“citybuildingNode110”)之间的冲突。所以你真的想要更像

      的东西
      nodename << childIteration << '_' << parentIteration;
      

      强制两个数字之间的分隔符。

      Documentation for std::stringstream.

      还有另一种可能的讨厌。我们刚刚提供给ogre的string只会在std::stringstream nodename存在的情况下存在,并且会在生成它的循环结束时死亡。我没有看到the documentation快速阅读的任何内容,即ogre自己制作了这个string的副本。所以请稍微调整一下以确保您不必将此名称存储在某个位置以防止它超出范围,被销毁,并使用dangling reference留下食人魔。