我正在使用XNA在C#中制作一个随机的城市生成器,基于一个瓦片为16x16的瓦片引擎。我已经以网格模式生成了道路,并将它们放在List<T>
中,其位置以像素为单位,也通过平铺坐标。因此,我将道路使用的瓷砖设置为“Occupied = true”,并尝试用建筑物填充剩余的未使用的瓷砖。
然而,困难在于我希望建筑纹理比仅仅一块瓷砖更大。我的瓷砖在另一个List<T>
中组织并具有占用属性,因此我可以检查天气是否已填充。因此,我需要检查32x32矩形中4个瓷砖的属性,以查看它们被占用的天气,如果没有在那里放置建筑物。
我已经实现了这一点,但它非常慢且效率低,因为它遍历每个磁贴并且每个循环检查整个列表4次。所以我正在寻找一种更好的方法来做到这一点。我也知道我的整个系统可能有点愚蠢,但我是新手,并且正在尝试用我有限的知识来实现这一目标。
foreach (Tile Tile in Tiles) {
Tile Tile1 = Tiles.Find(delegate(Tile T1) { return T1.TileCoords() ==
new Vector2(X, Y) && T1.Occupied == false; });
Tile Tile2 = Tiles.Find(delegate(Tile T1) { return T1.TileCoords() ==
new Vector2(X + 1, Y) && T1.Occupied == false; });
Tile Tile3 = Tiles.Find(delegate(Tile T1) { return T1.TileCoords() ==
new Vector2(X, Y + 1) && T1.Occupied == false; });
Tile Tile4 = Tiles.Find(delegate(Tile T1) { return T1.TileCoords() ==
new Vector2(X + 1, Y + 1) && T1.Occupied == false; });
if (Tile1 != null && Tile2 != null && Tile3 != null && Tile4 != null) {
MyBuildings.Add(new Buildings(new Rectangle(Tile1.Rectangle.X,
Tile1.Rectangle.Y, Engine.TileWidth * 2, Engine.TileHeight * 2)));
Tile1.Occupied = true;
Tile1.OccupiedWith = "Building";
Tile2.Occupied = true;
Tile2.OccupiedWith = "Building";
Tile3.Occupied = true;
Tile3.OccupiedWith = "Building";
Tile4.Occupied = true;
Tile4.OccupiedWith = "Building";
}
if (X > WorldSize.X / 16) {
X = 0;
Y++;
} else
X++;
}
答案 0 :(得分:0)
考虑将您的图块存储在二维数组中。这是基于平铺游戏的非常常见(如果不是最常见的)练习。现在你将它们存储在数组中,这对于遍历是非常低效的,因为你必须遍历整个数组来找到某个tile。使用二维数组,您可以通过以下方式搜索切片:
Tile T1 = Tiles[T1.X, t1.Y];
Tile T2 = Tiles[T1.X + 1, t1.Y];
Tile T3 = Tiles[T1.X, t1.Y + 1];
Tile T4 = Tiles[T1.X + 1, t1.Y + 1];
由于您的瓷砖标准尺寸为16像素,因此您可以轻松地在瓷砖之间进行转换。像素位置(绘图)及其在阵列中的位置,将它们除以或乘以16
答案 1 :(得分:0)
我建议改变你存储瓷砖的方式。
每个磁贴可以有一个List<Tile>
个邻居,采用8x8配置:
当你试图寻找一个自由空间时,你只需要线性地遍历8个邻居。
这种方式只有在创建地图时才需要计算邻居,并将它们存储在邻居列表中。
通过这种表示,您还可以更容易地使用某种模式(例如创建河流,道路等)在网格中游行。