You need to enable JavaScript to run this app. Godot Engine 如何通过代码用TileMap瓦片填充Polygon2D区域
优惠活动
大模型
产品
解决方案
定价
更多

Godot Engine 如何通过代码用TileMap瓦片填充Polygon2D区域

Godot 2D 基于TileMap的Polygon2D区域填充实现

核心实现逻辑

整个流程不需要手写复杂的多边形交叉判断,直接复用Godot内置的几何计算能力就能落地:

  • 统一坐标基准:所有判断逻辑都转到全局空间下计算,避免节点本地变换带来的坐标错位
  • 缩小遍历范围:只遍历多边形外接矩形覆盖的网格区域,不做全场景无意义循环
  • 用内置几何接口做包含判断:不需要自己实现射线检测逻辑,直接调用系统方法判断网格是否在多边形范围内

分步实现

  • 准备参数
    • 拿到目标Polygon2D节点,将其本地顶点数组转换为全局空间坐标集合
    • 读取TileMap的瓦片尺寸、要填充的瓦片坐标集合、对应瓦片集的source ID
  • 计算遍历边界
    • 遍历多边形所有顶点,拿到x、y方向的最小、最大值,确定外接矩形范围
    • 把外接矩形的边界值按TileMap的瓦片尺寸做向下取整,对齐到网格坐标,得到遍历的起始、结束网格坐标
  • 逐格填充判断
    • 对范围内的每一个网格坐标,计算对应瓦片的几何中心的全局坐标
    • 把中心坐标传入Geometry2D.is_point_in_polygon()接口,若返回真则在该网格位置放置指定瓦片

可直接复用的核心代码

extends TileMap
# 绑定要填充的目标多边形节点
@export var target_polygon: Polygon2D
# 要填充的瓦片在TileSet里的坐标
@export var fill_tile: Vector2i = Vector2i(0, 0)
# 瓦片对应的源ID
@export var tile_source_id: int = 0

func perform_fill() -> void:
    # 转换多边形顶点到全局坐标
    var global_poly_points := PackedVector2Array()
    for local_point in target_polygon.polygon:
        global_poly_points.append(target_polygon.global_transform * local_point)
    
    # 计算多边形外接矩形边界
    var bounds_min := Vector2(INF, INF)
    var bounds_max := Vector2(-INF, -INF)
    for point in global_poly_points:
        bounds_min.x = min(bounds_min.x, point.x)
        bounds_min.y = min(bounds_min.y, point.y)
        bounds_max.x = max(bounds_max.x, point.x)
        bounds_max.y = max(bounds_max.y, point.y)
    
    # 边界对齐到TileMap网格
    var tile_size := self.tile_size
    var grid_start := Vector2i(
        floori(bounds_min.x / tile_size.x),
        floori(bounds_min.y / tile_size.y)
    )
    var grid_end := Vector2i(
        floori(bounds_max.x / tile_size.x),
        floori(bounds_max.y / tile_size.y)
    )

    # 逐格判断并填充
    for y in range(grid_start.y, grid_end.y + 1):
        for x in range(grid_start.x, grid_end.x + 1):
            var current_grid := Vector2i(x, y)
            # 计算瓦片中心的全局坐标,作为判断点
            var tile_world_center := global_position + current_grid * tile_size + tile_size / 2
            if Geometry2D.is_point_in_polygon(tile_world_center, global_poly_points):
                set_cell(current_grid, tile_source_id, fill_tile)

常见踩坑提示

  1. 重点避坑:不要直接拿Polygon2D的本地顶点和TileMap的网格坐标直接做比对,两个节点如果存在位置偏移、缩放差异,会直接导致填充结果整体错位
  2. Godot 4.x版本的TileMap接口对旧版set_cell做了参数调整,实际运行时要对照当前版本的接口文档传参,避免瓦片无法正常加载
  3. 如果需要斜边边缘更顺滑,可以在中心判断的基础上,增加对瓦片四个角点的判断:只要有一个角点在多边形范围内,就放置对应瓦片,减少边缘锯齿

内容的提问来源于stack exchange,提问作者KanaszM

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.25 11:24:03