0

在过去的几周里,我一直在学习 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);
        }

一切都坦克,我得到1fps。这看起来很奇怪,更大的数字真的会使 DistanceSquared 函数的计算时间更长吗?为什么?还是有其他可能导致我失踪的原因?

我已经运行了几个性能分析器,但它们没有告诉我任何有用的信息,只是 DistanceSquared 占用了我绝大多数的 CPU 周期。如果它是 800x480 的正常值,那么我的游戏时间只有 38% 用于该循环。当我将数字从 800->8000/480->4800 更改时,我 90% 的时间都花在了循环中。这并不是说有更多的对象要调用,也不是要进行更多的数学运算,而是相同的数学运算,只是数字更大,那么为什么会有如此巨大的差异呢?

4

1 回答 1

0

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

于 2013-02-21T06:00:33.733 回答