在基于网格的游戏中放置墙壁/道路

3

我正在制作一个基于网格的游戏。

在这个游戏中,你可以放置建筑物、墙壁和道路。

当物体被放置在网格中时,我将单元格ID设置为该对象的ID。到目前为止,一切都很好,这个功能都能正常工作。

我的问题出现在我需要位掩码我的墙壁/道路(通过拖动鼠标放置)时。

目前我进行位掩码的方法是检查所有相邻的单元格是否匹配,并相应地设置正确的模型。例如,如果西边和北边有匹配项,则创建一个弯曲。

当我将墙壁放在已经占用的单元格上时,我的问题就出现了。我仍然希望以图形方式显示墙壁(呈红色),但我不能覆盖当前单元格中的内容。

这意味着我的位掩码不起作用,因为墙壁不在实际的网格中,它只存在于世界空间中。

墙将单元格设置为id 0,房屋将单元格设置为id 1。我无法覆盖房屋单元格中的id,因此位掩码(正确地)最终会破坏。

如何管理这样的场景?

单元格:

public class Cell
{
    public int x, z;
    public int id;
    public GameObject go
}

2
为什么网格上不能有多个层级? - Iggy
@Iggy 我正在考虑这个问题。你的意思是一个单元格可以容纳多个游戏对象吗? - Majs
1
不完全是。我想的是让网格对象包含图层列表,每个图层基本上都是单元格的列表。每个图层将用于特定类型(建筑、道路、墙壁),这样可以避免冲突。 - Iggy
@Iggy 只是为了明确,您是指创建几层网格还是几层单元格?因为墙壁仍然需要知道建筑物和道路的位置。如果您有一个清晰的想法,请编写答案 :) 我不需要代码,只需要逻辑。 - Majs
1个回答

1

你可以向网格中添加图层,只合并在同一图层上的单元格。

  • 道路与道路合并。
  • 墙壁与墙壁合并。

如果你想避免重叠的单元格,那么检查是否已经存在于其他图层中。从其他图层查找值还将允许你交叉合并单元格,但会增加很多复杂性。

这是一些伪代码:

enum Layer {
  Building,
  Wall,
  Road
}

struct Point {
  int x,y;
}

class Cell {
  Point point;
  int value;
}

class Cells {
  Dictionary<Point, Cell> cells; // mapping position to the cell object

  Cells(int width, int height) {
    for x in width
      for y in height
        Point point = new Point(x,y);
        cells.Add(point, new Cell(point, default))
  }

  Cell Get(Point point) => cells[point];
}

class Grid {
  Dictionary<Layer, Cells> layers; // mapping the layer enum to the cells group object

  Grid(int width, int height) {
    foreach layer in Layer
      layers.Add(layer, new Cells(width, height));
  }

  Cells GetLayer(Layer layer) {
    return layers[layer]
  }

  int GetValue(Point point, Layer layer) {
    return GetLayer(layer).Get(point).value;
  }

  bool IsValueInAllLayers(Point point, int value) {
    foreach layer in Layers
      if layer.Get(point).value != value
        return false;
    return true;
  }
}

// program entry point
void Main() {
  // construct a 10x10 grid
  Grid grid = new Grid(10, 10);

  Point mousePoint = new Point(2,2);

  // to place a building all layers have to be empty (0)
  if(grid.IsValueInAllLayers(mousePoint, 0)) {
    grid.SetValue(mousePoint, Layer.Building);
  }
}

我有一个问题,需要一些帮助。当使用2D数组时,循环遍历网格非常简单:{ for (int z = 0; z < grid.GetArray().GetLength(1); z++) { Gizmos.DrawLine(grid.GridToWorld(x, z), grid.GridToWorld(x, z + 1)); Gizmos.DrawLine(grid.GridToWorld(x, z), grid.GridToWorld(x + 1, z)); } }``` 如何使用嵌套字典实现这一点? - Majs
1
@Majs 如果您使用“Point”结构作为字典中的键,则需要在for循环中使用x,z值创建“Point”的新实例。您还需要公开网格的大小。 for x in grid.GetWidth()for z in grid.GetDepth()grid.GetCell(new Point(x, z), layer) - Iggy
当然,谢谢你! - Majs

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接