从大型类列表中选择多个类的最有效方法?

时间:2013-03-31 18:25:44

标签: c# xna-4.0

基本上我正在尝试在XNA 2D中创建一个tile引擎,我现在正在使用一个大的Tiles列表(我的类包含一个tile的所有数据)并选择那些在我的视图范围内,然后显示它们屏幕。

我遇到的问题显然是,我的整体Tiles列表越大,我在尝试挑选范围内的Tiles时会遇到更多的延迟。我目前正在for循环中使用Linq来选择磁贴,如下所示:

//loop from the maximum view at the top of the screen to the maximum view at the bottom
for (int height = topView; height < bottomView; height++)
{
    //loop from the maximum view to the left of the screen to the maximum view of the right
    for (int width = leftView; width < rightView; width++)
    {
        //select the tile at this grid position
        Tile t = tileList.Where(x => x.GridPosition == new Vector2(width, height)).FirstOrDefault();
        if (t != null)
        {
            //calculate the screen position and add it to the list of local tiles within range
            t.ScreenPosition = new Vector2(screenWidth * 30, screenHeight * 30);
            localList.Add(t);
        }
        else
        {
            //the tile wasn't found, add a random blank one to fill the gap.
            Tile brokenTile = new Tile(game, new Vector2(width, height), 9001);
            brokenTile.ScreenPosition = new Vector2(screenWidth * 30, screenHeight * 30);
            localList.Add(brokenTile);
        }
        //increment the screen width used to calculate the screen position
        screenWidth++;
    }
    //increment the screen height used to calculate the screen position and reset the width
    screenHeight++;
    screenWidth = 1;
}

我想知道是否有办法更有效地做到这一点,理想情况是减少在增加“地图”的整体尺寸和选择范围内的那些瓷砖时所经历的滞后。

我唯一能想到的是在加载地图时将总列表拆分为“块”的方法,并且只查看每个块以拉出Tiles ..但是我不太确定我是怎么做的d这样做是因为如果我需要从多个“块”中拉出节点,那可能会很麻烦 尽管如此,任何有关良好方法的帮助都会很棒!

非常感谢! :)

编辑:这是一些屏幕截图:http://i.imgur.com/RJmSYYF.pnghttp://i.imgur.com/LgwB8CJ.png

相比较

2 个答案:

答案 0 :(得分:0)

允许在k维空间中快速找到对象的集合是KD-Tree。

请参阅维基百科上的k-d treeGeometric Algorithms

我将KD树的Java实现移植到C#。请参阅RoboWiki上的User:Ojd/KD-Tree。你可以在那里下载代码。

K-D树的搜索时间 O(log n)


<强>更新

您的屏幕截图显示瓷砖放置在矩形网格中。为什么不使用二维数组存储瓷砖?

Tile[,] grid = new Tile[m,n];

现在选择瓷砖变得非常自然,因为您可以从屏幕位置计算它们在网格中的位置。像这样你可以直接通过他们的x-y索引访问它们,而不必在一个延迟列表中搜索它们。单个图块的访问时间为 O(1),即与图块总数无关。

答案 1 :(得分:0)

我会考虑使用某种形式的space partitioning,例如quadtree

这意味着根据位置将对象分配给常规大小的四边形。您将能够有效地确定哪些四边形是可见的,并且每个四边形将知道它包含哪些对象(尽管您需要在移动对象时对其进行管理)。