我一直在学习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,它完全顺畅&amp;一切都很完美。但是,如果我这样做:
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%的时间都花在循环中。它不像有更多的对象可以调用,或者更多的数学要做,它是相同的数学,只是数字更大,所以为什么会有这么大的差异呢?
答案 0 :(得分:0)
在计算之前尝试将您的世界标准化为[0-1,0-1]并查看它是否有任何影响,这样您的循环代码将完全相同,每个位置将在0-1范围内计算真实世界的位置只是在计算结束时将它们相乘