pyxen.GridMap
GridMap 是由行和列排列的单元格组成的空间容器。
它定义了图块布局、单元格大小、可选的图块图集,以及 GridBody 的碰撞空间。
有关碰撞概念,请参见碰撞。
构造函数
GridMap(
*,
rows=None,
columns=None,
size=None,
image=None,
tilemap=None
)
所有参数均为仅关键字参数。
参数
| 参数 | 类型 | 描述 |
|---|---|---|
rows | int | 网格行数 |
columns | int | 网格列数 |
size | (width, height) | 单元格大小(像素) |
image | str | 图块图集图像名称 |
tilemap | str | 用于预加载单元格的 .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
| 属性 | 类型 | 默认值 |
|---|---|---|
active | bool | True |
控制是否对此地图运行碰撞模拟。当为 False 时,不处理任何附加到此地图的 GridBody 的移动、碰撞或回调。
# Pause collisions (e.g. pause menu)
level.map.active = False
# Resume collisions
level.map.active = True
map.rows, map.columns
| 属性 | 类型 |
|---|---|
rows | int |
columns | int |
地图的尺寸(以格为单位):创建时给定的尺寸,或其 .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
)
参数
| 参数 | 类型 | 描述 |
|---|---|---|
row | int | 网格行索引 |
column | int | 网格列索引 |
tile | (x, y) | 图集中的图块坐标 |
tag | int | 可选碰撞标签 |
示例:设置图块
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)
参数
| 参数 | 类型 | 描述 |
|---|---|---|
row | int | 网格行索引 |
column | int | 网格列索引 |
返回值
| 值 | 类型 | 描述 |
|---|---|---|
tile | (x, y) 或 -1 | 图块在图集中的坐标;没有图块的单元格(空的,或只有标签)为 -1 |
tag | int | 单元格的标签,没有时为 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— 伤害区域
标签由你的游戏逻辑或碰撞系统解释。