1

我正在使用 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++;
}
4

2 回答 2

0

考虑将图块存储在二维数组中。这是基于图块的游戏非常常见(如果不是最常见的话)的做法。现在您将它们存储在数组中,这对于遍历非常低效,因为您必须遍历整个数组才能找到某个图块。使用二维数组,您可以通过以下方式搜索图块:

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

于 2012-07-10T11:27:57.100 回答
0

我建议改变你存储瓷砖的方式。

每个 tile 可以有List<Tile>一个 8x8 配置的邻居: 在此处输入图像描述

当你试图找到一个空闲空间时,你只需线性迭代 8 个邻居。

这种方式只有在创建地图时才需要计算邻居,并将它们存储在邻居列表中。

通过这种表示,您还可以发现使用特定模式(例如创建河流、道路等)更容易穿过网格。

于 2012-07-10T11:33:20.457 回答