Walking the path

Hi friends, I hope you all had a great week and weekend!

This week I’ve made some progress on my Little Red Riding Hood puzzle game, it’s now a fully functioning game, with 2 levels. I still have a lot to do before I can call that a finished product though:

Building on Heartbeast A* pathfinding

To implement my wolf pathfinding, I used HeartBeast’s Astar Implementation Script for TileMap Nodes in Godot . The debug is view is really neat, and the script easy to build from. I had to modify it slightly for my use case:

Indexing cells by their grid position

In the original script, all the cells, units and obstacle are indexed using their real world position.
Let’s focus on the cells:

func create_pathfinding_points() -> void:
	astar.clear()
	var used_cell_positions = get_used_cell_global_positions()
	for cell_position in used_cell_positions:
		astar.add_point(get_point(cell_position), cell_position)

func get_used_cell_global_positions() -> Array:
	var cells = get_used_cells()
	var cell_positions := []
	for cell in cells:
		var cell_position := global_position + map_to_world(cell)
		cell_positions.append(cell_position)
	return cell_positions

I’m now indexing only based on the cell position in the grid:

func create_pathfinding_points() -> void:
	astar.clear()
	#var used_cell_positions = get_used_cell_global_positions()
	var used_cell_positions = get_used_cells()
	for cell_position in used_cell_positions:
		var cell_world_position = global_position + map_to_world(cell_position) + cell_size/2
		astar.add_point(get_point(cell_position), cell_world_position)

I also took the opportunity to register the center of the cell directly, as it’s what I found myself needing the most.

Movement

The movement is heavily inspired by this tutorial by GDQuest , but instead of directly checking if the point is walkable, I’m using the paths built with astar:

func _process(delta):
	var input_direction = get_input_direction()
	if not input_direction:
		return
		
	var cell_start = Grid.world_to_map(position)
	var cell_target = cell_start + input_direction
	var path_points = Grid.get_astar_path_avoiding_obstacles(cell_start, cell_target)
	if len(path_points) > 1:
		move_to(path_points[1])
	else:
		bump()

Objects

I also needed to have interactable objects on the grid, so I’m registering them exactly like the obstacles:

func add_object(object: Object) -> void:
	objects[get_point(world_to_map(object.position))] = object
	if not object.is_connected("tree_exiting", self, "remove_object"):
		object.connect("tree_exiting", self, "remove_object", [object])
				
func remove_object(object: Object) -> void:
	objects.erase(object)

And then in the movement script above I’m adding:

	var path_points = Grid.get_astar_path_avoiding_obstacles(cell_start, cell_target)
	if len(path_points) > 1:
		move_to(path_points[1])
		var object = Grid.get_object_on_cell(position)
		if object:
			object.interact()

Before I let you go, here are some interesting links I came across this week:

 

All right, that’s all for this week.
It has a bit heavier on the code side than usual, I hope it was your cup of tea!

Thanks for reading and see you next week!