pyxen.GridMap

A GridMap is a spatial container made of cells arranged in rows and columns.

It defines the tile layout, cell size, optional tile atlas, and the collision space for GridBody.

For collision concepts, see Collision.


Constructor

GridMap(
    *,
    rows=None,
    columns=None,
    size=None,
    image=None,
    tilemap=None
)

All parameters are keyword-only.


Parameters

ParameterTypeDescription
rowsintNumber of grid rows
columnsintNumber of grid columns
size(width, height)Cell size in pixels
imagestrTile atlas image name
tilemapstrName of a .tilemap asset to preload cells from

Example

level_map = GridMap(
    rows=10,
    columns=16,
    size=(16, 16),
    image="tileset"
)

Loading from a .tilemap asset

A .tilemap asset (created in the built-in Tilemap editor) stores the grid dimensions, cell size, tileset image, and every painted tile with an optional collision tag. Pass its name — without the extension — to tilemap= and all four geometry parameters plus every cell is preloaded automatically:

# Editor produced Assets/level1.tilemap
level = world.spawn(map=GridMap(tilemap="level1"))

Explicit rows/columns/size/image still win over values read from the asset, so the same tilemap can back a smaller debug view:

# Test with a 4×4 preview of the same tilemap
preview = GridMap(tilemap="level1", rows=4, columns=4)

When the dimensions are overridden the preloaded cells and things are discarded — the grid starts empty and you can paint it with map.set() as usual. Otherwise the map’s things come with it.


Attaching a GridMap

During spawn:

level = world.spawn(
    map=GridMap(
        rows=10,
        columns=16,
        size=(16, 16),
        image="tileset"
    )
)

Or later:

entity = world.spawn()
entity.map = GridMap(rows=8, columns=8, size=(16, 16))

Properties

map.active

PropertyTypeDefault
activeboolTrue

Controls whether collision simulation runs for this map. When False, no body movement, collisions, or callbacks are processed for any GridBody attached to this map.

# Pause collisions (e.g. pause menu)
level.map.active = False

# Resume collisions
level.map.active = True

map.rows, map.columns

PropertyType
rowsint
columnsint

The map’s size in cells: what it was made with, or what its .tilemap was painted at. Read-only. Times the cell size, they give the map’s size in pixels, for a camera’s bounds or to keep a body inside the map.

# The map's size in pixels
w = level.map.columns * 16
h = level.map.rows * 16

Modifying Tiles

Use map.set() to configure tiles.

map.set(
    row=0,
    column=1,
    tile=(tile_column, tile_row),
    tag=optional_tag
)

Parameters

ParameterTypeDescription
rowintGrid row index
columnintGrid column index
tile(x, y)Tile coordinates in the atlas
tagintOptional collision tag

Example: Set a Tile

level.map.set(
    row=2,
    column=5,
    tile=(3, 1)
)

Example: Add Collision Tag

level.map.set(
    row=4,
    column=2,
    tile=(0, 0),
    tag=1  # wall
)

Reading Tiles

map.get(row, column) answers what is at a cell, as a pair (tile, tag): what map.set() put there, or what the .tilemap painted.

tile, tag = level.map.get(row, column)

Parameters

ParameterTypeDescription
rowintGrid row index
columnintGrid column index

Returns

ValueTypeDescription
tile(x, y) or -1The tile’s coordinates in the atlas; -1 for a cell with no tile (empty, or a tag alone)
tagintThe cell’s tag, 0 when it has none

Outside the map, get answers (-1, 0) rather than an error, so a game can look one cell past an edge.

Example: Read a Cell

tile, tag = level.map.get(4, 2)
if tag == 1:
    print("a wall")
if tile == -1:
    print("nothing painted here")

Things

A .tilemap can name things on its cells: a chest, a door, the hero’s start. map.things() lists them as (name, row, column), by row, then column. A map without things, or built with explicit rows/columns, gives an empty list.

village = world.spawn(map=GridMap(tilemap="village"))

for name, row, column in village.map.things():
    if name == "chest":
        place_chest(row, column)   # the game's own function

A thing’s name is a sprite’s name, or a kind’s name: a kind is a name for one sprite’s frame, so two kinds can be drawn from one sprite (a slime and a guard). A cell holds one thing. Nothing moves or draws a thing; your code decides what each name becomes. Each call gives a new list, which you can sort or empty freely.

In the file, both are optional keys, left out when empty:

"kinds": [ {"frame": 1, "name": "guard", "sprite": "slime"} ],
"things": [ {"column": 16, "name": "chest", "row": 1} ]

Grid Coordinates

  • Rows increase vertically
  • Columns increase horizontally

Indices outside bounds are safely ignored.


GridMap + GridBody

A GridBody interacts with the GridMap for collision, movement resolution, and trigger detection.

GridBody must be a child of the GridMap entity.

level = world.spawn(
    map=GridMap(
        rows=8,
        columns=8,
        size=(16, 16),
        image="tiles"
    )
)

player = world.spawn(
    body=GridBody(),
    parent=level
)

Minimal Example: Basic Level

level = world.spawn(
    map=GridMap(
        rows=8,
        columns=8,
        size=(16, 16),
        image="tiles"
    )
)

# Create floor
for r in range(8):
    for c in range(8):
        level.map.set(row=r, column=c, tile=(0, 0))

# Create walls
for c in range(8):
    level.map.set(row=0, column=c, tile=(1, 0), tag=1)
    level.map.set(row=7, column=c, tile=(1, 0), tag=1)

Tags

tag is optional metadata per tile.

Typical uses:

  • 0 — empty
  • 1 — wall
  • 2 — water
  • 3 — damage zone

Tags are interpreted by your gameplay or collision system.


Snippets

In Pyxen’s home, under Snippets:

  • GridMap(tilemap=…) — Load a tilemap asset (size, image, tiles, tags).
  • map.set() — Paint tiles programmatically.
  • map.wrap_x — Self-wrapping world. Camera pans to show the seam.
  • map.hit() — Query whether a tagged tile overlaps a rectangle.