9func world_draw_rect(panel_size:Vector2, options:Dictionary = {}) -> Rect2:
10 var min_side := float(options.get(
"min_side", 1.0))
11 var side = max(min_side, min(panel_size.x, panel_size.y))
12 var position = Vector2(
13 (panel_size.x - side) * 0.5,
14 (panel_size.y - side) * 0.5
16 return Rect2(position, Vector2(side, side))
19func camera_rect(player_position:Vector2, tile_size:float, camera_config:Dictionary = {}) -> Rect2:
20 var visible_radius = camera_visible_radius(camera_config)
21 var render_tiles = float(visible_radius) * 2.0 + 2.0
22 var player_center_tiles = player_position / max(1.0, tile_size)
24 player_center_tiles.x - (render_tiles * 0.5),
25 player_center_tiles.y - (render_tiles * 0.5)
27 return Rect2(start * tile_size, Vector2(render_tiles, render_tiles) * tile_size)
30func camera_visible_radius(camera_config:Dictionary = {}) -> int:
31 return max(2, int(camera_config.get(
"visible_radius", 6)))
34func camera_visible_tiles(camera_config:Dictionary = {}) -> Vector2i:
35 var visible_radius = camera_visible_radius(camera_config)
36 var fixed_tiles = max(5, visible_radius * 2 + 1)
37 return Vector2i(fixed_tiles, fixed_tiles)
40func visible_world_rect(camera_rect:Rect2, world_bounds:Rect2) -> Rect2:
41 var left = max(camera_rect.position.x, world_bounds.position.x)
42 var top = max(camera_rect.position.y, world_bounds.position.y)
43 var right = min(camera_rect.position.x + camera_rect.size.x, world_bounds.position.x + world_bounds.size.x)
44 var bottom = min(camera_rect.position.y + camera_rect.size.y, world_bounds.position.y + world_bounds.size.y)
45 if right <= left
or bottom <= top:
47 return Rect2(Vector2(left, top), Vector2(right - left, bottom - top))
50func cell_origin(cell:Vector2i, tile_size:float) -> Vector2:
51 return Vector2(float(cell.x) * tile_size, float(cell.y) * tile_size)
54func cell_center(cell:Vector2i, tile_size:float) -> Vector2:
55 return cell_origin(cell, tile_size) + Vector2(tile_size * 0.5, tile_size * 0.5)
58func world_point_to_panel(point:Vector2, camera_rect:Rect2, draw_rect:Rect2) -> Vector2:
59 if camera_rect.size == Vector2.ZERO:
61 return draw_rect.position + Vector2(
62 (point.x - camera_rect.position.x) / camera_rect.size.x * draw_rect.size.x,
63 (point.y - camera_rect.position.y) / camera_rect.size.y * draw_rect.size.y
67func world_rect_to_panel(rect:Rect2, camera_rect:Rect2, draw_rect:Rect2) -> Rect2:
68 var top_left = world_point_to_panel(rect.position, camera_rect, draw_rect)
69 var bottom_right = world_point_to_panel(rect.position + rect.size, camera_rect, draw_rect)
70 return Rect2(top_left, bottom_right - top_left)
73func cell_rect_to_panel(cell:Vector2i, tile_size:float, camera_rect:Rect2, draw_rect:Rect2) -> Rect2:
74 return world_rect_to_panel(Rect2(cell_origin(cell, tile_size), Vector2(tile_size, tile_size)), camera_rect, draw_rect)
77func cell_in_visible_world(cell:Vector2i, tile_size:float, visible_world_rect:Rect2) -> bool:
78 return visible_world_rect.has_point(cell_center(cell, tile_size))
81func cell_in_visible_object_range(cell:Vector2i, player_cell:Vector2i, tile_size:float, visible_world_rect:Rect2, radius:int) -> bool:
82 if not cell_in_visible_world(cell, tile_size, visible_world_rect):
84 return max(abs(cell.x - player_cell.x), abs(cell.y - player_cell.y)) <= radius
87func world_point_in_visible_world(point:Vector2, visible_world_rect:Rect2) -> bool:
88 return visible_world_rect.has_point(point)
91func grid_line_ranges(visible_world_rect:Rect2, tile_size:float, grid_size:Vector2i) -> Dictionary:
92 if visible_world_rect.size.x <= 0.0
or visible_world_rect.size.y <= 0.0:
93 return {
"start_x": 0,
"end_x": 0,
"start_y": 0,
"end_y": 0}
95 "start_x": clamp(int(floor(visible_world_rect.position.x / tile_size)), 0, grid_size.x),
96 "end_x": clamp(int(ceil((visible_world_rect.position.x + visible_world_rect.size.x) / tile_size)), 0, grid_size.x),
97 "start_y": clamp(int(floor(visible_world_rect.position.y / tile_size)), 0, grid_size.y),
98 "end_y": clamp(int(ceil((visible_world_rect.position.y + visible_world_rect.size.y) / tile_size)), 0, grid_size.y)