pyxen.GridMap

GridMap 是由行和列排列的单元格组成的空间容器。

它定义了图块布局、单元格大小、可选的图块图集,以及 GridBody 的碰撞空间。

有关碰撞概念,请参见碰撞。


构造函数

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

所有参数均为仅关键字参数。


参数

参数类型描述
rowsint网格行数
columnsint网格列数
size(width, height)单元格大小(像素)
imagestr图块图集图像名称
tilemapstr用于预加载单元格的 .tilemap 资源名称

示例

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

附加 GridMap

在生成时:

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

或稍后:

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

属性

map.active

属性类型默认值
activeboolTrue

控制是否对此地图运行碰撞模拟。当为 False 时,不处理任何附加到此地图的 GridBody 的移动、碰撞或回调。

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

# Resume collisions
level.map.active = True

map.rows, map.columns

属性类型
rowsint
columnsint

地图的尺寸(以格为单位):创建时给定的尺寸,或其 .tilemap 绘制时的尺寸。只读。乘以格子尺寸即为地图的像素尺寸,可用于相机的边界,或让物体留在地图内。

# 地图的像素尺寸
w = level.map.columns * 16
h = level.map.rows * 16

修改图块

使用 map.set() 配置图块。

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

参数

参数类型描述
rowint网格行索引
columnint网格列索引
tile(x, y)图集中的图块坐标
tagint可选碰撞标签

示例:设置图块

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

示例:添加碰撞标签

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

读取图块

map.get(row, column) 以 (tile, tag) 二元组告诉你某个单元格里有什么:map.set() 放在那里的内容,或 .tilemap 绘制的内容。

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

参数

参数类型描述
rowint网格行索引
columnint网格列索引

返回值

值类型描述
tile(x, y) 或 -1图块在图集中的坐标;没有图块的单元格(空的,或只有标签)为 -1
tagint单元格的标签,没有时为 0

在地图之外,get 返回 (-1, 0) 而不是报错,因此游戏可以查看边缘之外的一格。

示例:读取单元格

tile, tag = level.map.get(4, 2)
if tag == 1:
    print("a wall")
if tile == -1:
    print("这里没有绘制任何东西")

物件

.tilemap 可以在单元格上命名物件(things):宝箱、门、主角的起点。map.things() 以 (name, row, column) 列表返回它们,先按行再按列排序。没有物件的地图,或用显式 rows/columns 创建的地图,返回空列表。

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

for name, row, column in village.map.things():
    if name == "chest":
        place_chest(row, column)   # 游戏自己的函数

物件的名称是一个精灵的名称,或一个种类(kind)的名称:种类是精灵某一帧的名称,因此一个精灵可以画出两个种类(slime 和 guard)。一个单元格只有一个物件。没有什么会移动或绘制物件;每个名称变成什么由你的代码决定。每次调用都返回一个新列表,可以随意排序或清空。

在文件中,两者都是可选键,为空时省略:

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

网格坐标

  • 行垂直增加
  • 列水平增加

超出范围的索引会被安全忽略。


GridMap + GridBody

GridBody 与 GridMap 交互以进行碰撞、移动处理和触发检测。

GridBody 必须是 GridMap 实体的子节点。

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

player = world.spawn(
    body=GridBody(),
    parent=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)

标签

tag 是每个图块的可选元数据。

典型用途:

  • 0 — 空
  • 1 — 墙壁
  • 2 — 水
  • 3 — 伤害区域

标签由你的游戏逻辑或碰撞系统解释。