Scale down Vector2 coordinates from TileMapLayer for minimap

Godot Version

4.3

Context

I want to create a minimap based on the TileMapLayers I used.

I iterate over all my TileMapLayers, calculate the scale based on the Minimap size and create the pixels on the image.

I can’t wrap my hand around the correct way to calculate this.
Either the maps are small in the corner or the width is correct but not the height, like in the screenshot.

Code of the current implementation:

func create_minimap():
	var maps := get_tree().get_nodes_in_group("map")
	var image := Image.create_empty(64, 64, false, Image.FORMAT_RGB8)
	
	for map: TileMapLayer in maps:
		var map_scale = Vector2(1.0, 1.0)
		#map_scale = Vector2(image.get_size()) / Vector2(map.get_used_rect().size)
		map_scale = Vector2(image.get_size()) / (get_viewport().get_visible_rect().size / Vector2(map.tile_set.tile_size))

		for cell_coords in map.get_used_cells():
			var tile = map.get_cell_tile_data(cell_coords)
			var color_coords = (
				(Vector2(map.get_used_rect().position))
				+
				(Vector2(cell_coords))
			)
			image.fill_rect(Rect2(Vector2(color_coords) * map_scale, map_scale.max(Vector2(1, 1))), tile.get_custom_data("color"))
	
	%Minimap.texture = ImageTexture.create_from_image(image)

Right now I get the visible viewport rect, because that’s all I have right now while I’m testing this. In the future the TileMapLayer size will be bigger than the viewport.

The fill_rect I think I should use to account for scales that aren’t square.

Screenshot:

Question

How do I calculate the scale correctly?

Seems like I did calculate the scale correctly. I added the TileMapLayer used_rect position as an offset because I thought that’s what was needed to place the pixel rects, but what I wanted to do was add their global_position (and probably divide that by the tile_size). But since they are Vector2(0, 0) I’ll omit that then for now.

I guess I got confused somwhere in-between the testing.

Writing this question and stepping back for a few moments did the trick again. :slight_smile:

Working solution:

func create_minimap():
	var maps := get_tree().get_nodes_in_group("map")
	var image := Image.create_empty(64, 64, false, Image.FORMAT_RGB8)
	
	for map: TileMapLayer in maps:
		var map_scale = Vector2(1.0, 1.0)
		#map_scale = Vector2(image.get_size()) / Vector2(map.get_used_rect().size)
		map_scale = Vector2(image.get_size()) / (get_viewport().get_visible_rect().size / Vector2(map.tile_set.tile_size))
		
		for cell_coords in map.get_used_cells():
			var tile = map.get_cell_tile_data(cell_coords)
			image.fill_rect(
				Rect2(Vector2(cell_coords) * map_scale, (map_scale + Vector2(1,1)).max(Vector2(1, 1))),
				tile.get_custom_data("color")
			)
	
	%Minimap.texture = ImageTexture.create_from_image(image)

The (map_scale + Vector2(1,1)) is there to close any half-step pixel holes in the Minimap.

Screenshot:

20241006_10h48m50s_grim

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.