我正在尝试对我的游戏对象进行碰撞检查。我有一个multimap,它包含每个键中相同类型的对象。键表示对象的类型。但是,所有类型都来自同一个类。我需要将它们分开,以便当一种类型的对象触摸另一种类型的另一个对象时,对象知道该怎么做。但似乎我检查碰撞的方式非常慢,因为我注意到我添加的对象越多,移动的速度就越慢。谁能帮我? :(
以下是确切的代码:
void CheckCollisions()
{
if (!Actors.empty())
{
std::multimap<std::string, boost::shared_ptr<std::vector<PActor>>>::const_iterator it;
it = Actors.begin();
while (it != Actors.end())
{
for (int i = 0; i < static_cast<int>(it->second->size()); i++)
{
std::multimap<std::string, boost::shared_ptr<std::vector<PActor>>>::const_iterator it2;
it2 = Actors.begin();
while(it2 != Actors.end())
{
for (int j = 0; j < static_cast<int>(it2->second->size()); j++)
{
if (i != j)
{
if (Touch(it->second->at(i), it2->second->at(j)))
{
it->second->at(i)->Touch(it2->first, it2->second->at(j));
it2->second->at(j)->Touch(it->first, it->second->at(i));
}
}
}
it2++;
}
}
it++;
}
}
}
注意: PActor只是Actor的shared_ptr;
答案 0 :(得分:1)
碰撞检测就是要尽量减少你必须做的检查次数。例如,除非你的演员很少,否则你应该不检查每个演员与其他演员。这是一个O(N ^ 2)算法,当你添加actor时,它的扩展性不是很好(数字加倍需要四倍)。也许你知道每个演员的大小?然后你可以尝试与这个范围内的演员碰撞。有一个名为ANN的库可以用来很快找到最近的邻居。
祝你好运!答案 1 :(得分:0)
你的算法基本上是对象数量的二次方,所以难怪它随着对象数量的增加而变慢。
我会应用某种分段:您可以根据对象的位置将对象拆分为不同的列表,这样只有相同或相邻列表的对象才会发生碰撞。这样,您的比较次数就会变小。
另一个流行的优化是仅检查自上次检查后已移动的对象,这可能(或可能不)排除很多静态对象。