-
Notifications
You must be signed in to change notification settings - Fork 0
Core.GridSystem.SingleEntityGrid
The class is a generic utility designed to manage objects (entities) on a 2D coordinate system. It uses a dictionary to map integer coordinates () to specific instances of type . SingleEntityGrid<T>``PointInt``T
-
Coordinate-Based Storage: It doesn't use a fixed-size 2D array. Instead, it uses a , meaning it only consumes memory for the cells that actually contain an entity.
Dictionary -
Single Entity per Cell: As the name suggests, each key can only point to one entity. If you a new entity on an occupied cell, it overwrites the previous one.
PointInt``Register -
Area Support: It allows you to register or remove an entity over a range of cells using a (rectangle). This is useful for large objects that occupy multiple tiles.
Rect -
Grid Wrapping ()
stayInGrid: The method has a unique feature where if is true, it performs a modulo operation (% 100). This suggests the grid is intended to "wrap around" within a 100x100 area.Get``stayInGrid
-
Register(PointInt cell, T entity): Places an entity at a specific X, Y coordinate. -
Register(Rect cells, T entity): Fills all coordinates within the rectangle's bounds with the same entity reference. -
IsOccupied(PointInt cell): A quick way to check if a tile is "blocked" or has something in it. -
Get(PointInt cell, bool stayInGrid = false): Retrieves the entity. If the grid wraps, it ensures the coordinate stays within the 0-99 range.
Here are a few ways you might use this class in a game context:
If you are building a tile-based game, you might use this to track buildings or walls.
// Define a grid for Buildings
var buildingGrid = new SingleEntityGrid<Building>();
// Place a small 1x1 building (like a Lamp)
PointInt lampPos = new PointInt(10, 5);
buildingGrid.Register(lampPos, new Building("Street Lamp"));
// Check if a spot is free before building
PointInt targetPos = new PointInt(10, 5);
if (!buildingGrid.IsOccupied(targetPos))
{
buildingGrid.Register(targetPos, new Building("House"));
}
else
{
Console.WriteLine("Cannot build here: Spot occupied!");
}If you have a large structure, like a 3x3 "Command Center", you can register it across all the tiles it covers.
var commandCenter = new Building("Command Center");
// Define a rectangle: Left=5, Top=5, Width=3, Height=3
Rect area = new Rect(5, 5, 3, 3);
// This marks all 9 tiles as occupied by this one building
buildingGrid.Register(area, commandCenter);
// Later, if we check any tile within that 3x3 area, we get the same building
if (buildingGrid.TryGet(new PointInt(6, 6), out var entity))
{
Console.WriteLine($"Found: {entity.Name}"); // Output: Found: Command Center
}The indexer allows you to treat the grid like a simple 2D array, and you can use the logic for "infinite" or looping worlds. stayInGrid
// Accessing via Indexer (standard access)
var entityAtOrigin = buildingGrid[new PointInt(0, 0)];
// Accessing with wrapping logic (e.g., checking position 105, which wraps to 5)
PointInt farPos = new PointInt(105, 5);
var wrappedEntity = buildingGrid.Get(farPos, stayInGrid: true);
// Removing an entity
buildingGrid.Remove(new PointInt(10, 5));The method contains a hardcoded value: . This implies that this specific implementation is tailored for a world size of 100x100. If your game world is larger or smaller, you would need to modify that specific line or make the grid size a variable. Get``cell = new PointInt(cell.X % 100, cell.Y % 100);