【发布时间】:2021-01-27 17:29:53
【问题描述】:
我正在尝试为我的游戏提出一个碰撞算法,但我正在为实现它的方法而苦苦挣扎。我有一个碰撞盒对象,其中包含所有相关的碰撞数据,然后在我的游戏对象中有一个 CollisionBox* 向量来处理每个碰撞器。
但是我的方法需要为每次碰撞调用相同的函数 4 次,并且嵌套循环保证在循环完成之前将多次检查相同的碰撞,并且每帧都会调用它,因此性能会很差.这是我写的
void Game::CheckCollisions() {
vector<CollisionBox*>::iterator it;
for (it = colBoxes.begin(); it != colBoxes.end(); ++it) {
//for each box - compare the 4 corner points with every other box , only compare different collision layers
Vector3 boxPos = (*it)->mModel.GetPosition();
for (vector<CollisionBox*>::iterator it_2 = colBoxes.begin(); it_2 != colBoxes.end(); ++it_2) {
if ((*it) != (*it_2) && (*it)->colLayer != (*it_2)->colLayer && (*it)->isActive && (*it_2)->isActive) {
IsPointInside((*it)->tl, *(*it_2)); //tl
IsPointInside((*it)->tr, *(*it_2)); //tr
IsPointInside((*it)->bl, *(*it_2)); //bl
IsPointInside((*it)->br, *(*it_2)); //br
}
}
}
}
bool Game::IsPointInside(const DirectX::SimpleMath::Vector3& point, CollisionBox& box) {
return (point.x >= box.bl.x && point.x <= box.tl.x) &&
(point.y >= box.bl.y && point.y <= box.tl.y);
}
【问题讨论】:
-
检测您的代码以进行性能测量以找到瓶颈。鉴于详细而狭窄的背景,很难说出应该改变什么。
-
例如,您可以尝试第一个
it_2框是当前it框(或下一个),以避免执行冗余测试。 -
如果碰撞盒不是全部堆叠在游戏世界的一小块区域中,您可能希望将地图划分为例如 200 * 200 个图块(总共 40,000 个图块)的网格。然后,您可以为每个网格图块维护与该网格接触的所有碰撞框的列表。这样,如果您想确定与某个碰撞盒的所有碰撞,您所要做的就是将该碰撞盒与该碰撞盒所接触的网格图块中的碰撞盒列表进行比较。您将不再需要与游戏世界中的所有碰撞盒进行比较。
-
我之前评论中描述的方法只有在不是所有碰撞盒都堆叠在游戏世界的一小块区域时才有意义。如果是,那么您可能想改用R-tree。
标签: c++ collision-detection game-physics