距离检查性能

本文关键字:性能 检查 距离 | 更新日期: 2023-09-27 18:00:24

在过去的几周里,我一直在学习C#/XNA,试图制作一款游戏,所以这可能是一个明显的新手,但现在是:

我一直在制作一个相当简单的2D游戏,所以我有一个大约1000个对象(NPC)的列表,我非常频繁地迭代它们,对每个对象进行距离检查。问题是,当我增加距离时,一切都会大大减慢,以至于比赛无法进行,我真的不明白为什么。

当距离较短时(如果所有对象都在一个800x480世界大小内),它工作得很好,但当距离增加时(比如8000x4800世界大小),我的性能会下降。

以下是一些相关的代码(显然不是全部,因为这将是太多的东西,但这是正在发生的事情的要点):

List<Human> humans;
List<Enemy> enemies;
public void Update(City city, float gameTime)
{
    humans = city.GetHumans();
    enemies = city.GetEnemies();
    for (int h = 0; h < humans.Count; h++)
    {
        Vector2 human_position = humans[h].position;
        Vector2 nearestEnemyPosition = Vector2.Zero;
        for (int e = 0; e < enemies.Count; e++)
            {
                Vector2 enemy_position = enemies[e].position;
                float distanceToEnemy = Vector2.DistanceSquared(human_position, enemy_position);
                if (distanceToEnemy < distanceToNearestEnemy)
                {
                    distanceToNearestEnemy = distanceToEnemy;
                    nearestEnemyPosition = enemy_position;
                }
                if (distanceToNearestEnemy < 2500f)
                {
                     logic code here (very little performance impact)
                }
            }
        for (int hh = 0; hh < humans.Count; hh++)
            {
                if (h == hh)
                {
                    continue;
                }
                if (humanMoved == true)
                {
                    continue;
                }
                Vector2 other_human_position = humans[hh].position;
                if (Vector2.DistanceSquared(human_position, other_human_position) < 100f)
                {
                   do more stuff here (movement code, no performance impact)
                }

我的敌人名单也有几乎相同的循环。

制作它们的代码在这里:

foreach (Human human in this.humans)
        {
            Vector2 position = new Vector2(random.Next(800), random.Next(480));
            human.Spawn(position);
        }

这很好用。我得到60fps,它是完全平滑的&一切都运行得很完美。然而,如果我这样做:

foreach (Human human in this.humans)
        {
            Vector2 position = new Vector2(random.Next(8000), random.Next(4800));
            human.Spawn(position);
        }

所有东西都倒了,我得到1磅。这看起来很奇怪,更大的数字真的会让DistanceSquared函数需要更长的计算时间吗?为什么?或者是其他什么原因导致了我的失踪?

我已经运行了几个性能评测程序,他们没有告诉我什么有用的,只是DistanceSquared占用了我绝大多数的CPU周期。如果是800x480的正常值,我只有38%的游戏时间花在了这个循环中。当我将数字从800->8000/480->4800更改时,90%的时间都花在了循环中。这并不是说有更多的对象要调用,或者有更多的数学运算要做,这是相同的数学运算,只是有更大的数字,那么为什么会有如此巨大的差异呢?

距离检查性能

在计算之前,尝试将您的世界标准化为[0,1,0-1],看看它是否有任何影响,这样您的循环代码将完全相同,每个位置都在0-1范围内,要计算真实世界的位置,只需在计算结束时将它们相乘即可。