我正在创建C ++ / SFML游戏引擎。每个"实体"在游戏中有一个指向它的指针存储在Entity类的静态向量中,称为entityRenderList
。在游戏循环的每次迭代中,此向量按冒泡排序算法排序,以便以正确的顺序绘制精灵。
每当删除一个实体时,它都会用NULL指针替换向量中的指针。默认情况下,我的算法应该导致它找到的任何NULL指针被排序到向量的后面,随后它们被移除。
以下是排序算法的代码:
bool Entity::depthSortFunction(Entity* a, Entity* b)
{
if (b==NULL) return false; //any NULL values are moved to the back
if (a==NULL) return true;
else return (a->depth_) < (b->depth_);
}
void Entity::sortEntityRenderList()
{
if (entityRenderList.size()>1) {
//Any NULL values are brought to the top to be stripped off.
bool passMade=false;
Entity* temp;
int n=entityRenderList.size()-1;
for(int i=0; i<n; i++)
{
passMade=false;
for(int j=0; j<n-1; j++)
{
if(depthSortFunction(entityRenderList[j],entityRenderList[j+1]))
{
//then swap them
temp = entityRenderList[j+1];
entityRenderList[j+1] = entityRenderList[j];
entityRenderList[j] = temp;
//and then notify the entities of the change
if (entityRenderList[j]!=NULL) {entityRenderList[j]->renderListID=j;}
if (entityRenderList[j+1]!=NULL) {entityRenderList[j+1]->renderListID=j+1;}
passMade=true;
//std::cout<<"Swapping entries "<<j<<" and "<<j+1<<"...\n";
}
}
if (!passMade) {
break; //then it is sorted, as we have not needed to modify the array.
}
}
}
//Now, we strip off any NULL values from the top.
while (!entityRenderList.empty() && entityRenderList.back()==NULL) {
entityRenderList.pop_back(); //strip off last one
}
}
应该发生的是在每次运行算法时从向量中删除任何NULL指针。但是,情况并非如此,任何NULL指针都保持原样,并且看起来根本没有排序。
注意:那里有passMade
布尔值,这样如果进行了数组的传递并且没有进行交换,算法就会停止。
任何帮助将不胜感激。提前谢谢。
编辑:排序算法代码略微修改为here。
答案 0 :(得分:1)
j
循环限制中存在错误。例如,如果列表包含10个元素,n
为9,n-1
为8,则j
的最大值为7.循环可以交换10的元素7和8元素清单。它无法交换最后一对,即元素8和9。
正如评论所建议的那样,使用已经过测试和工作的库排序会更好更简单。您可以在最后一次通过列表中完成所有操作,而不是随着时间调整renderListID
字段。如果在弹出NULL
元素后执行此操作,则无需在该循环中测试NULL
。
for(int i=0; i<entityRenderList.size(); i++)
{
entityRenderList[i]->renderListID=i;
}