【发布时间】:2019-01-19 17:05:42
【问题描述】:
我正在创建一种 2D 地图,其中的坐标附有 tile 类,
tile 类将在其中包含其坐标,以及稍后将访问的其他一些值,但我希望该映射没有大小限制。问题是,我想在该地图中查看一些 tile 内部的值,例如:我在 coord(25,30) 并且我想知道每个相邻的 tile 类中的布尔值tile.
-
如果我使用数组,我可能有最快的方法来检查
tile的坐标,例如2 个索引的数组。我可以将每个索引分别设为 x 和 y 坐标,因此我只会在看到tile上的值时检查该坐标。 但地图会有大小限制。 -
如果我使用列表地图将没有大小限制,但我无法直接检查坐标,所以我需要通过每个创建的
tileforeach循环,并检查该图块内的坐标是否与我要查找的坐标相同。 -
我目前的解决方案是有一个只有坐标的第二个列表,并在我创建图块时分配它,因此坐标列表中的索引与图块列表中的索引相同。因此,当我需要检查某个图块时,我会执行
CoordinateList.Contains(coordinate),如果这是真的,那么我将该坐标的索引作为代码应该在tile列表中查找的索引。
我想要一种更快的方法来检查图块,没有大小限制。
到目前为止,使用
tile列表,我每次检查整个地图的时间大约为 3200 毫秒(列表中大约有 2000 个tiles)。使用
mapCoord列表,我得到了大约 1500 毫秒(大约 2000 个图块和坐标)。使用数组,我得到了非常快的响应(从未测量过),但肯定不到我的第二次……因为我从来不用检查整个数组,而是检查某个索引。
更容易理解我的问题的示例:
注意1:它不会填满整个数组。
注意2:它并不总是矩形的。
int size = 50;
Tile[,] mapArray = new Tile[size,size];
List<Tile> mapList = new List<Tile>();
List<Vector2Int> mapCoord = new List<Vector2Int>();
void CreateMap()
{
for(int x = size/2; size <= size/2; x++)
{
for(int y = size/2; size <= size/2; y++)
{
if(x > 2 && y > 3)
{
mapArray[x,y] = new Tile(new Vector2Int(x,y), false, 32);
mapList.add(new Tile(new Vector2Int(x,y), false, 32));
mapCoord.add(new Vector2Int(x,y));
}
}
}
}
所以如果我要检查数组中的tile,我只会检查数组中的坐标,因为tile 坐标与数组索引相同,但它会有大小限制。
如果我要检查列表中的图块,我需要像这样执行foreach 循环。对性能和优化非常不利。
Tile desiredTile = null;
for each(Tile tile in mapTiles)
{
if(tile.Coord == DesiredCoord)
desiredTile = tile;
}
到目前为止,最好的方法是检查mapCoord 列表,如下所示:
if(mapCoord.Contains(desiredCoord))
{
desiredTile = mapList[mapCoord.IndexOf(DesiredCoord)];
}
【问题讨论】:
-
size <= size/2曾经会变成true吗?检查你的循环条件。 -
查找“稀疏数组”作为一种方法。一种可能的实现是字典,其中键实际上是两个整数(x 和 y)的元组。如果游戏以标准边界开始(比如起点的 +/- 100),您可以混合和匹配 200x200 数组和除此之外的字典。您还可以通过将多个矩形区域作为一个数组来获得创意。
-
@spender 它是一种类型,它的意思是 x = -size/2 不是正数,y 也一样
-
@Flydog57 字典真的为我做了,从 1500 毫秒到几乎 10 毫秒,你的想法真的很好,谢谢...
标签: c# arrays list unity3d optimization