XNA平铺引擎,放置比tile更大的纹理

时间:2012-07-10 11:05:57

标签: c# xna

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

2 个答案:

答案 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配置: enter image description here

当你试图寻找一个自由空间时,你只需要线性地遍历8个邻居。

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

通过这种表示,您还可以更容易地使用某种模式(例如创建河流,道路等)在网格中游行。