69 lines
3.0 KiB
GDScript
69 lines
3.0 KiB
GDScript
@tool
|
|
extends Node2D
|
|
|
|
@export var grid_size: float = 50.0
|
|
|
|
func _ready():
|
|
set_process(true)
|
|
|
|
func _process(delta):
|
|
queue_redraw()
|
|
|
|
func _draw():
|
|
var camera_transform = get_viewport().get_canvas_transform()
|
|
var camera_scale = camera_transform.get_scale().x
|
|
var line_width = 1.0 / camera_scale
|
|
|
|
# Get the visible rectangle in world coordinates.
|
|
var viewport_rect_in_world = camera_transform.affine_inverse() * get_viewport().get_visible_rect()
|
|
var visible_rect_min = viewport_rect_in_world.position
|
|
var visible_rect_max = viewport_rect_in_world.end
|
|
|
|
# --- Draw the Axes (always 2px thick in screen space) ---
|
|
draw_line(Vector2(visible_rect_min.x, 0), Vector2(visible_rect_max.x, 0), Color.RED, 2 / camera_scale)
|
|
draw_line(Vector2(0, visible_rect_min.y), Vector2(0, visible_rect_max.y), Color.GREEN, 2 / camera_scale)
|
|
|
|
# --- Draw the Major Grid Lines with Culling ---
|
|
var major_step = grid_size
|
|
const MIN_SCREEN_SPACING = 30.0 # Minimum pixel spacing between grid lines.
|
|
# Skip lines if they would be too close on screen.
|
|
while major_step * camera_scale < MIN_SCREEN_SPACING:
|
|
major_step *= 2
|
|
|
|
var first_x_major = floor(visible_rect_min.x / major_step) * major_step
|
|
var last_x_major = ceil(visible_rect_max.x / major_step) * major_step
|
|
var first_y_major = floor(visible_rect_min.y / major_step) * major_step
|
|
var last_y_major = ceil(visible_rect_max.y / major_step) * major_step
|
|
|
|
# Draw major vertical lines
|
|
for x in range(int(first_x_major / major_step), int(last_x_major / major_step) + 1):
|
|
var draw_x = x * major_step
|
|
draw_line(Vector2(draw_x, visible_rect_min.y), Vector2(draw_x, visible_rect_max.y), Color(Color.GRAY, 0.5), line_width)
|
|
|
|
# Draw major horizontal lines
|
|
for y in range(int(first_y_major / major_step), int(last_y_major / major_step) + 1):
|
|
var draw_y = y * major_step
|
|
draw_line(Vector2(visible_rect_min.x, draw_y), Vector2(visible_rect_max.x, draw_y), Color(Color.GRAY, 0.5), line_width)
|
|
|
|
# --- Draw Minor Grid Lines (only when zoomed in) ---
|
|
if major_step == grid_size:
|
|
var minor_step = grid_size / 5.0
|
|
var first_x_minor = floor(visible_rect_min.x / minor_step) * minor_step
|
|
var last_x_minor = ceil(visible_rect_max.x / minor_step) * minor_step
|
|
var first_y_minor = floor(visible_rect_min.y / minor_step) * minor_step
|
|
var last_y_minor = ceil(visible_rect_max.y / minor_step) * minor_step
|
|
|
|
# Draw minor vertical lines
|
|
for x in range(int(first_x_minor / minor_step), int(last_x_minor / minor_step) + 1):
|
|
var draw_x = x * minor_step
|
|
# Skip major lines to avoid drawing over them.
|
|
if fmod(draw_x, major_step) != 0:
|
|
draw_line(Vector2(draw_x, visible_rect_min.y), Vector2(draw_x, visible_rect_max.y), Color(Color.GRAY, 0.2), line_width)
|
|
|
|
# Draw minor horizontal lines
|
|
for y in range(int(first_y_minor / minor_step), int(last_y_minor / minor_step) + 1):
|
|
var draw_y = y * minor_step
|
|
# Skip major lines to avoid drawing over them.
|
|
if fmod(draw_y, major_step) != 0:
|
|
draw_line(Vector2(visible_rect_min.x, draw_y), Vector2(visible_rect_max.x, draw_y), Color(Color.GRAY, 0.2), line_width)
|