PAYATHON 2026

Godot 小地图为什么无法正确生成负方向房间?

数据小许

结论

从代码看,主要问题在于生成房间时用 roomspawn.position 计算候选位置,却用 previousposition 更新 roompos、roomcoords 和 roomdata。这样一来,实际生成的位置可能与记录的位置不一致,候选房间也没有被正确保存。四个方向都会受影响,负方向运算本身没有特殊问题。

让生成位置和记录位置保持一致

计算出候选位置后,把它保存到同一个变量中,并在检查、放置节点和记录数据时都使用这个变量。下面的代码示意如何替换原有的方向选择和记录逻辑。其中,map_origin 应设置为把世界坐标换算成房间坐标时使用的原点。按现有表达式,它对应 Vector2(960, 540)。

var dirs = [-1, 1]
var upordown = randi_range(1, 2)
var direction = dirs[randi() % dirs.size()]
var candidate_position: Vector2
var tries = 0

while true:
    if upordown == 1:
        candidate_position = Vector2(
            previousposition.x + tilesize * direction,
            previousposition.y
        )
    else:
        candidate_position = Vector2(
            previousposition.x,
            previousposition.y + tilesize * direction
        )

    if candidate_position not in roompos:
        break

    upordown = randi_range(1, 2)
    direction = dirs[randi() % dirs.size()]
    tries += 1

    if tries > 100:
        # 在此处处理没有可用相邻位置的情况,并确保重新计算 candidate_position。
        break

roomspawn.position = candidate_position
roomspawn.roomcoords = (candidate_position - map_origin) / tilesize
roompos.append(candidate_position)
roomdata[str(counter)] = {
    "location": candidate_position,
    "color": roomspawn.tilecolor,
    "enemies": roomspawn.enemies.duplicate(),
    "roomcoords": roomspawn.roomcoords,
    "roomtype": 2
}
add_child(roomspawn)

如果要让房间沿路径继续延伸,生成成功后还需更新 previousposition = candidate_position。如果要从已有房间随机分支,可以继续从 roompos 中选择起点;生成后记得把实际的候选位置加入 roompos,避免再次把起点加入列表。原脚本在 tries > 100 时会修改 previousposition,还需检查该分支是否重新计算并验证了候选位置,避免记录未实际放置的房间。

检查小地图坐标

在 Godot 的 2D 坐标系中,x 增大表示向右,y 增大表示向下;x、y 为负值时分别表示向左、向上。小地图的位置计算可以处理负坐标,但房间节点的位置和 roomcoords 需要使用同一份坐标数据。检查 player.currentpos 和 room.roomcoords 的含义与单位是否一致:如果一个是世界坐标,另一个是以房间为单位的网格坐标,直接比较或相乘就会造成偏移。

此外,_draw() 每次重绘都会实例化一组新节点并调用 add_child(),而 _process() 每帧都会调用 queue_redraw()。这样会反复添加小地图瓦片,导致节点不断累积。如果这些瓦片只用于绘制,可以在 _draw() 中使用绘图方法(例如 draw_rect()),根据 room.roomcoords 计算矩形位置;也可以复用或清理现有瓦片后再添加新节点。

注意事项

贴出的脚本没有展示完整的缩进和房间坐标类型上下文,因此示例只说明如何统一坐标。还需确认 roompos 保存的是世界像素坐标还是房间网格坐标,并在生成、保存、恢复和绘制时使用同一套坐标体系。

备注:内容仅供参考。