本文主要是介绍【Godot4.2】2D导航04 - TileMap导航的逻辑,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
基于NavigationRegion2D
我们基于NavigationRegion2D的逻辑一文的场景结构,但是将NavigationRegion2D
删除,更改为TileMap节点。
为TileMap创建Tileset,并创建一个导航层。在TileSet面板中,为草地和黄色泥土地面图块绘制可通行区域(整个矩形)。这样做的含义是只有这连个图块允许通行,其余图块全是障碍物。
切换至TileMap面板,利用矩形和直线绘制方式绘制一个简单的有出口的地图。
运行场景,会发现基于NavigationAgent2D
的导航在TileMap上依旧是可行的。
## 基于AStarGrid2D
可以看出基于NavigationRegion2D
的导航总还是有些不尽如人意的地方,偶尔就卡在了半路上。
AStarGrid2D
本身基于网格,那么它与TileMap
组合可以说是“天作之合”。
删除Player的NavigationRegion2D
以及脚本。
查看icon.svg可以发现其图片大小为128×128,而我们的tileset的cell_size为16×16,所以为了将玩家显示在一个网格里,我们需要将icon.svg缩放为16×16。
128/16=8,所以我们需要将其设为原来的1/8,也就是缩小到原来的0.125倍。相应调整碰撞形状的大小。
移动玩家到某个单元格内。
将world2的脚本改成如下:
# world2.gd
extends Node2D@onready var player = $Player
@onready var tile_map = $TileMap
var astar_grid = AStarGrid2D.new()
var move_speed = 200.0
var path:PackedVector2Array
var solids:PackedVector2Arrayfunc _ready():# 获取tile_map包含所有已绘制图块的矩形var rect = tile_map.get_used_rect()# 构建AStarGrid2Dastar_grid.size = rect.sizeastar_grid.cell_size = tile_map.tile_set.tile_sizeastar_grid.offset = astar_grid.cell_size/2astar_grid.update()# 获取所有已经绘制的图块的数组var cells = tile_map.get_used_cells(0)for cell in cells:# TileData包含图块的信息var data:TileData = tile_map.get_cell_tile_data(0,cell)if !data.get_navigation_polygon(0): # 如果图块没有设置导航solids.append(cell)astar_grid.set_point_solid(cell,true) # 设为障碍物# 左键点击,获取导航目标位置
func _input(event):if event is InputEventMouseButton:if event.button_index == MOUSE_BUTTON_LEFT and event.is_pressed():# TileMap的local_to_map()用于将屏幕坐标转化为TileMap的网格坐标var p1 = tile_map.local_to_map(player.position)var p2 = tile_map.local_to_map(get_global_mouse_position())path = astar_grid.get_point_path(p1,p2)queue_redraw()# 实现沿着路径行走
func _process(delta):if path.size() > 0:var target_pos = path[0]if target_pos.distance_to(player.position)>2:player.velocity = player.position.direction_to(target_pos) * move_speedplayer.move_and_slide()else:path.remove_at(0)queue_redraw()# 绘制路径信息
func _draw():var grid_width = astar_grid.size.x * astar_grid.cell_size.xvar cell_width = astar_grid.cell_size.xvar cell_height = astar_grid.cell_size.y# 绘制路径和其上的点if path.size() > 0:for pot in path:draw_circle(pot,5,Color.YELLOW)draw_polyline(path,Color.YELLOW,2)
开启显示碰撞区域和导航。
运行后的效果如下:
基本的导航还是可以的。
:::success
提示
默认由于TileMap是world2的子节点,所以world2上用_draw绘制的内容会被TileMap绘制的地图覆盖而无法显示。解决方法是将TileMap的z_index设为-1。
:::
这篇关于【Godot4.2】2D导航04 - TileMap导航的逻辑的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!