extends Node2D @export var line_width: float = 25.0 @export var allowed_distance: float = 60.0 @export var selected_shape: String = "rombo" @export var shape_scale: float = 1.0 @export var margin_ratio: float = 0.1 var shape_points: PackedVector2Array var current_progress := 0 var fail_count := 0 var tracking := false var shape_presets := {} func _ready(): get_viewport().connect("size_changed", Callable(self, "_on_viewport_resized")) _create_shape_presets() _draw_selected_shape() func _draw_selected_shape(): var screen_size = get_viewport().get_visible_rect().size var center = screen_size / 2.0 var min_dim = min(screen_size.x, screen_size.y) var scale = (min_dim * shape_scale * (1.0 - margin_ratio * 2)) / 2 if shape_presets.has(selected_shape): var original = shape_presets[selected_shape] var interpolated = _interpolate_shape(original, 100, true) shape_points = PackedVector2Array() for point in interpolated: var scaled_point = center + (point * scale) shape_points.append(scaled_point) else: print("⚠️ Forma no encontrada:", selected_shape) return $ShapeLine.points = shape_points $ShapeLine.width = line_width $ShapeLine.default_color = Color.GRAY $ShapeLine.texture = null $ProgressLine.clear_points() $ProgressLine.points = [] $ProgressLine.width = line_width $ProgressLine.default_color = Color.GREEN $ProgressLine.texture = null current_progress = 0 fail_count = 0 tracking = false func _on_viewport_resized(): _draw_selected_shape() func _unhandled_input(event): if event is InputEventScreenTouch or event is InputEventMouseButton: if event.pressed: tracking = true current_progress = 0 fail_count = 0 $ProgressLine.clear_points() else: tracking = false elif (event is InputEventScreenDrag or event is InputEventMouseMotion) and tracking: if current_progress >= shape_points.size(): return var pos = event.position var nearest_point = -1 var min_distance = allowed_distance for i in range(current_progress, shape_points.size()): var dist = pos.distance_to(shape_points[i]) if dist < min_distance: min_distance = dist nearest_point = i if nearest_point != -1: current_progress = nearest_point $ProgressLine.add_point(shape_points[nearest_point]) if current_progress >= shape_points.size() - 1: tracking = false print("✅ ¡Forma completada!") print("❌ Errores:", fail_count) else: fail_count += 1 print("❌ Fuera de la línea. Total:", fail_count) func _create_shape_presets(): shape_presets = { "cuadrado": [Vector2(-1, -1), Vector2(1, -1), Vector2(1, 1), Vector2(-1, 1)], "triangulo": [Vector2(0, -1), Vector2(1, 1), Vector2(-1, 1)], "casa": [Vector2(-1, 1), Vector2(-1, 0), Vector2(0, -1), Vector2(1, 0), Vector2(1, 1)], "paraguas": [Vector2(-1, 0.5), Vector2(1, 0.5), Vector2(0, -1), Vector2(-1, 0.5), Vector2(0, 1)], "diamante": [Vector2(0, -1), Vector2(1, 0), Vector2(0, 1), Vector2(-1, 0)], "linea": [Vector2(-1, 0), Vector2(1, 0)], "rectangulo": [Vector2(-1, -0.5), Vector2(1, -0.5), Vector2(1, 0.5), Vector2(-1, 0.5)], "rombo": [Vector2(0, -1), Vector2(1, 0), Vector2(0, 1), Vector2(-1, 0)], "circulo": generate_circle(Vector2.ZERO, 1), "estrella": generate_star(Vector2.ZERO, 1), "corazon": generate_heart(Vector2.ZERO, 1) } func _interpolate_shape(points: PackedVector2Array, density: int = 100, closed: bool = true) -> PackedVector2Array: var interpolated := PackedVector2Array() var count = points.size() for i in range(count): var a = points[i] var b = points[(i + 1) % count] if closed or i < count - 1 else null if b != null: for j in range(density): var t = float(j) / density interpolated.append(a.lerp(b, t)) return interpolated func generate_circle(center: Vector2, radius: float, segments: int = 64) -> PackedVector2Array: var points := PackedVector2Array() for i in range(segments + 1): var angle = 2.0 * PI * float(i) / float(segments) points.append(center + Vector2(cos(angle), sin(angle)) * radius) return points func generate_star(center: Vector2, radius: float, spikes: int = 5) -> PackedVector2Array: var points := PackedVector2Array() var inner_radius = radius * 0.5 for i in range(spikes * 2): var r = radius if i % 2 == 0 else inner_radius var angle = PI / float(spikes) * i points.append(center + Vector2(cos(angle), sin(angle)) * r) points.append(points[0]) return points func generate_heart(center: Vector2, size: float) -> PackedVector2Array: var points := PackedVector2Array() for t in range(0, 360, 10): var rad = deg_to_rad(t) var x = size * 16 * pow(sin(rad), 3) var y = -size * (13 * cos(rad) - 5 * cos(2 * rad) - 2 * cos(3 * rad) - cos(4 * rad)) points.append(center + Vector2(x, y)) points.append(points[0]) return points