基于AOE2 Parser的Python地图方形树木生成坐标计算求助
解决方案:AOE2 Parser实现网格行道树与交界石头放置
一、明确AOE2坐标对应逻辑
结合你的代码与地图规则,统一坐标逻辑:
- 瓦片坐标:X从左到右递增(0=最左侧,
map_width-1=最右侧);Y从上到下递增(0=最顶部,map_height-1=最底部) - 单位放置坐标:瓦片中心位置为
(tile_x + 0.5, tile_y + 0.5),你的代码中这部分是正确的
二、实现网格状行道树围方形区域
要围出方形,只需在方形四条边上生成树木,而非遍历整个区域,以下分两种场景实现:
场景1:四边密植树木(每个瓦片都种)
先定义方形边界(根据水域宽度调整偏移量),再分别遍历四条边:
# 定义方形边界(瓦片坐标,避开水域) square_x_start = largeur_eau + 5 square_x_end = map_manager.map_width - largeur_eau - 5 square_y_start = largeur_eau + 5 square_y_end = map_manager.map_height - largeur_eau - 5 excluded_terrain = [TerrainId.SNOW, TerrainId.SNOW_LIGHT, TerrainId.ICE, TerrainId.ROCK_1, water_arround_arena, TerrainId.BEACH_ICE] tree_id = OtherInfo.TREE_SNOW_PINE.ID # 顶部边:y固定为上边界,遍历x范围 for x in range(square_x_start, square_x_end + 1): tile = map_manager.get_tile(x, square_y_start) if tile.terrain_id not in excluded_terrain: unit_manager.add_unit( player=P0, unit_const=tree_id, x=x + 0.5, y=square_y_start + 0.5, z=0, rotation=0, animation_frame=0, ) # 底部边:y固定为下边界,遍历x范围 for x in range(square_x_start, square_x_end + 1): tile = map_manager.get_tile(x, square_y_end) if tile.terrain_id not in excluded_terrain: unit_manager.add_unit( player=P0, unit_const=tree_id, x=x + 0.5, y=square_y_end + 0.5, z=0, rotation=0, animation_frame=0, ) # 左侧边:x固定为左边界,遍历y范围(跳过上下边避免重复) for y in range(square_y_start + 1, square_y_end): tile = map_manager.get_tile(square_x_start, y) if tile.terrain_id not in excluded_terrain: unit_manager.add_unit( player=P0, unit_const=tree_id, x=square_x_start + 0.5, y=y + 0.5, z=0, rotation=0, animation_frame=0, ) # 右侧边:x固定为右边界,遍历y范围(跳过上下边避免重复) for y in range(square_y_start + 1, square_y_end): tile = map_manager.get_tile(square_x_end, y) if tile.terrain_id not in excluded_terrain: unit_manager.add_unit( player=P0, unit_const=tree_id, x=square_x_end + 0.5, y=y + 0.5, z=0, rotation=0, animation_frame=0, )
场景2:四边间隔种树(网格状)
在循环中加入步长参数step,实现间隔种植:
step = 2 # 每2个瓦片种一棵 # 顶部边间隔种树 for x in range(square_x_start, square_x_end + 1, step): tile = map_manager.get_tile(x, square_y_start) if tile.terrain_id not in excluded_terrain: unit_manager.add_unit( player=P0, unit_const=tree_id, x=x + 0.5, y=square_y_start + 0.5, z=0, rotation=0, animation_frame=0, ) # 底部边间隔种树 for x in range(square_x_start, square_x_end + 1, step): tile = map_manager.get_tile(x, square_y_end) if tile.terrain_id not in excluded_terrain: unit_manager.add_unit( player=P0, unit_const=tree_id, x=x + 0.5, y=square_y_end + 0.5, z=0, rotation=0, animation_frame=0, ) # 左侧边间隔种树 for y in range(square_y_start + 1, square_y_end, step): tile = map_manager.get_tile(square_x_start, y) if tile.terrain_id not in excluded_terrain: unit_manager.add_unit( player=P0, unit_const=tree_id, x=square_x_start + 0.5, y=y + 0.5, z=0, rotation=0, animation_frame=0, ) # 右侧边间隔种树 for y in range(square_y_start + 1, square_y_end, step): tile = map_manager.get_tile(square_x_end, y) if tile.terrain_id not in excluded_terrain: unit_manager.add_unit( player=P0, unit_const=tree_id, x=square_x_end + 0.5, y=y + 0.5, z=0, rotation=0, animation_frame=0, )
三、实现水与陆地交界处放置石头
遍历所有瓦片,检测当前瓦片为陆地且相邻有水域时,放置石头:
# 定义水域地形集合 water_terrains = [water_arround_arena, TerrainId.ICE, TerrainId.BEACH_ICE] # 定义允许放置石头的陆地地形 allowed_land_terrains = [t for t in TerrainId if t not in excluded_terrain and t not in water_terrains] stone_id = TerrainId.ROCK_1 # 替换为你需要的石头单位ID # 遍历所有瓦片(跳过边界避免索引越界) for x in range(1, map_manager.map_width - 1): for y in range(1, map_manager.map_height - 1): current_tile = map_manager.get_tile(x, y) if current_tile.terrain_id in allowed_land_terrains: # 检查上下左右四个相邻瓦片是否有水域 neighbors = [ map_manager.get_tile(x+1, y), map_manager.get_tile(x-1, y), map_manager.get_tile(x, y+1), map_manager.get_tile(x, y-1) ] if any(neighbor.terrain_id in water_terrains for neighbor in neighbors): unit_manager.add_unit( player=P0, unit_const=stone_id, x=x + 0.5, y=y + 0.5, z=0, rotation=0, animation_frame=0, )
四、注意事项
- 调整方形边界参数时,需确保数值在
0到map_width/map_height范围内,避免索引越界 - 若需要更精准的石头放置位置,可根据相邻水域的方向微调坐标(比如相邻水域在右侧,石头放在
x+0.8, y+0.5) - 测试时可缩小遍历范围,避免一次性生成过多单位导致卡顿
内容的提问来源于stack exchange,提问作者Maselia
相关产品推荐
相关产品推荐

