性能问题:更新简单人群模拟列表

时间:2012-03-04 11:43:39

标签: performance list simulation

我正在为小型游戏进行简单的flok或群集模拟。

这种行为对我的需求来说是不错的,但表现并非如此。

基本上我有很多物体(士兵),需要在移动到航点时展开。

我在这里写了一个简单版本的代码:

List<Soldier> avoidList = new List<Soldier>();

foreach (Soldier s in gameWorld)
{
    if (this == s)
         continue;

    if (Distance(s, this) <= 5)
    {
         avoidList.Add(s);
    }
}

CalculateNewDirection(avoidList);

基本上,每个士兵都会检查场景中其他士兵的距离,并根据太近的士兵计算方向。

Like this picture.

现在我正在浏览x ^ 2个对象。

因此,如果我有100个对象,我会运行100 ^ 2 = 10.000个对象,只是为了更新每个单独的对象avoidList。

如果我将它调到500个物体,我会运行250,000个物体。

Theres必须采用另一种更聪明的方式来做到这一点!

希望有人能赐教我:)

1 个答案:

答案 0 :(得分:1)

在我的头顶上,看起来你在计算距离时正在做一个不必要的平方根。您可以检查平方距离,并检查平方常数。

此外,还有一项改进,如果你发现一名士兵要避开,另一名士兵也会避开第一名士兵。因此,如果您跟踪多个避免列表,则每对只需要检查一次。

这可以通过仅保存太靠近的对来完成。在伪代码中

for (int i = 0; i < numSoldiers - 1; ++i) {
    for (int j = i + 1; j < numSoldiers; ++j) {
        if (Distance(soldier[i], soldier[j]) < 5) {
            closePairs.Add(new Pair(i, j));
        }
    }
}

// Calculate directions based on the pairs found.

这些是基本的优化。如果你需要更深入,你需要根据位置对士兵进行排序。如果你跟踪每个5个单位的士兵,那么超过2个方格的士兵就不会影响给定的士兵。

首先在X和Y轴上对士兵进行排序也会给出类似的机会,因为你知道如果一个轴上下一个人的距离大于半径,则无需检查距离。

这会让你获得更好的表现,但这取决于你的数据以及士兵通常的稀疏程度。