Majs
Majs

Reputation: 66

Placing walls/roads in a grid-based game

I am making a grid-based game.

In this game you can place buildings, walls, roads.

When something is placed in a grid, I set the cell id to that objects id. So far so good, this all works.

My problem comes when I need to Bitmask my walls/roads (placed by dragging mouse).

Currently the way I do bitmasking is I check all neighboring cells for a match, and set the correct model accordingly. I.e if there is a match west and north, I create a bend.

My problem comes when I place my wall on top of already occupied cells. I still want to display the wall graphically (tinted red), but I can ofc not overwrite what is currently in that cell.

This means my bitmasking wont work because the wall is not in the actual grid, it's only in world space.

Walls set cells to id 0, and houses set cell to id 1. I cant overwrite the id in the house cell, so bitmasking (correctly) end up breaking.

How can a scenario like this be managed?

Cell:

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

Upvotes: 3

Views: 245

Answers (1)

Iggy
Iggy

Reputation: 4888

You can add layers to the grid and only merge the cells that are on the same layer.

  • Roads merge with roads.
  • Walls merge with walls.

If you want to avoid overlapping cells, then check if something already exists in any other layer. Looking up values from other layers will also allow you to cross-merge cells, though it adds a lot of complexity.

Here's some pseudo-code:

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);
  }
}

Upvotes: 1

Related Questions