extends Node2D @export var shapes: Array = [] @export var radius: float = 300 @export var width: float = 5 @export var circle_color: Color = Color(1, 1, 1, 1) var num_points = 100 var points = [] var segment_colors = [] # === ESTADÍSTICAS === var start_time : int var end_time : int var fallos : int = 0 var segmentos_visitados = [] var resultados_formas = {} # Diccionario para guardar los resultados de cada forma var juego_finalizado = false var forma_actual_index = 0 # Índice de la forma actual en el array 'shapes' var forma_actual_nombre : String # Nombre de la forma actual func _ready(): iniciar_forma() func iniciar_forma(): if forma_actual_index < shapes.size(): forma_actual_nombre = shapes[forma_actual_index] print("Empezando forma:", forma_actual_nombre) start_time = Time.get_unix_time_from_system() fallos = 0 segmentos_visitados.clear() points = get_shape_points() segment_colors.resize(points.size() - 1) segmentos_visitados.resize(points.size() - 1) for i in range(segment_colors.size()): segment_colors[i] = circle_color segmentos_visitados[i] = false juego_finalizado = false queue_redraw() else: finalizar_juego() func _process(delta): update_center() func update_center(): var screen_size = get_viewport_rect().size position = screen_size / 2 func _draw(): points = get_shape_points() for i in range(points.size() - 1): draw_line(points[i], points[i + 1], segment_colors[i], width) for point in points: draw_circle(point, width / 2, circle_color) func _input(event): if juego_finalizado: return if event is InputEventScreenDrag: var local_pos = to_local(event.position) var closest_index = get_closest_point_index(local_pos) if closest_index != -1: segment_colors[closest_index] = Color(0, 1, 0, 1) segmentos_visitados[closest_index] = true if is_completed(): finalizar_nivel() else: fallos += 1 queue_redraw() func get_closest_point_index(pos: Vector2) -> int: var min_dist = 20 var closest_index = -1 for i in range(points.size() - 1): var mid_point = (points[i] + points[i + 1]) / 2 var dist = pos.distance_to(mid_point) if dist < min_dist: min_dist = dist closest_index = i return closest_index # === DETECCIÓN DE FINALIZACIÓN === func is_completed() -> bool: for visited in segmentos_visitados: if not visited: return false return true func finalizar_nivel(): end_time = Time.get_unix_time_from_system() juego_finalizado = true guardar_resultado_forma() forma_actual_index += 1 iniciar_forma() func guardar_resultado_forma(): var duracion = end_time - start_time resultados_formas[forma_actual_nombre] = { "tiempo": duracion, "fallos": fallos } print("Resultados de", forma_actual_nombre, ":", resultados_formas[forma_actual_nombre]) func finalizar_juego(): var mensaje_final = "🎉 ¡Juego Completado!\n\nResultados por forma:\n" for forma in resultados_formas: var resultado = resultados_formas[forma] mensaje_final += "%s: Tiempo: %s seg, Fallos: %s\n" % [forma, resultado.tiempo, resultado.fallos] var popup = Label.new() popup.text = mensaje_final popup.position = Vector2(50, 50) popup.add_theme_color_override("font_color", Color(1,1,1)) popup.add_theme_font_size_override("font_size", 20) add_child(popup) # === Formas === func get_shape_points(): match forma_actual_nombre : # Usamos la forma actual para dibujar "CircleButton": return get_circle_points() "StarButton": return get_star_points() "heart": return get_heart_points() "TriangleButton": return get_polygon_points(3) "SquareButton": return get_square_points() "diamond": return get_polygon_points(4, true) "cross": return get_cross_points() "arrow": return get_arrow_points() "HouseButton": return get_house_points() "UmbrellaButton": return get_umbrella_points() _: return [] func get_circle_points(): var result = [] for i in range(num_points + 1): var angle = i * (2 * PI / num_points) result.append(Vector2(cos(angle), sin(angle)) * radius) return result func get_square_points(): var result = [] # Definimos la mitad del tamaño del lado del cuadrado basado en el radio del círculo para que sea similar en tamaño var half_side = radius * 0.5 # Definimos las cuatro esquinas del cuadrado result.append(Vector2(-half_side, -half_side)) # Esquina superior izquierda result.append(Vector2(half_side, -half_side)) # Esquina superior derecha result.append(Vector2(half_side, half_side)) # Esquina inferior derecha result.append(Vector2(-half_side, half_side)) # Esquina inferior izquierda result.append(Vector2(-half_side, -half_side)) # Volvemos a la primera esquina para cerrar el cuadrado # Ahora, vamos a añadir puntos intermedios entre las esquinas para que se puedan colorear los segmentos var num_segments = 10 # Podemos ajustar cuántos puntos hay en cada lado var points_per_segment = num_points / 4 # Repartimos los puntos entre los 4 lados result.clear() # Empezamos de nuevo con los puntos para los segmentos for i in range(points_per_segment + 1): var t = float(i) / points_per_segment result.append(lerp(Vector2(-half_side, -half_side), Vector2(half_side, -half_side), t)) # Lado superior for i in range(points_per_segment + 1): var t = float(i) / points_per_segment result.append(lerp(Vector2(half_side, -half_side), Vector2(half_side, half_side), t)) # Lado derecho for i in range(points_per_segment + 1): var t = float(i) / points_per_segment result.append(lerp(Vector2(half_side, half_side), Vector2(-half_side, half_side), t)) # Lado inferior for i in range(points_per_segment + 1): var t = float(i) / points_per_segment result.append(lerp(Vector2(-half_side, half_side), Vector2(-half_side, -half_side), t)) # Lado izquierdo result.append(Vector2(-half_side, -half_side)) # Cerramos la figura return result func get_star_points(): var result = [] var num_puntas = 5 # Número de puntas de la estrella var double_points = num_puntas * 2 var angle_step = TAU / double_points # TAU = 2 * PI var outer_radius = radius * 0.8 var inner_radius = radius * 0.4 for i in range(double_points + 1): # +1 para cerrar la figura var angle = i * angle_step - PI / 2 # Rota para que una punta quede arriba var r = outer_radius if i % 2 == 0 else inner_radius result.append(Vector2(cos(angle), sin(angle)) * r) return result func get_heart_points(): var result = [] for i in range(num_points + 1): var t = i * (2 * PI / num_points) var x = 16 * pow(sin(t), 3) var y = -(13 * cos(t) - 5 * cos(2*t) - 2 * cos(3*t) - cos(4*t)) # Invertir para que mire hacia arriba result.append(Vector2(x, y) * (radius / 15.0)) # Escalar para que quepa return result func get_polygon_points(sides: int, rotated := false): var result = [] var angle_offset = PI / sides if rotated else 0 for i in range(sides + 1): var angle = angle_offset + i * (2 * PI / sides) result.append(Vector2(cos(angle), sin(angle)) * radius * 0.8) # Un poco más pequeño return result func get_cross_points(): var thickness = radius * 0.2 var length = radius * 0.6 return [ Vector2(-thickness/2, -length/2), Vector2(thickness/2, -length/2), Vector2(thickness/2, -thickness/2), Vector2(length/2, -thickness/2), Vector2(length/2, thickness/2), Vector2(thickness/2, thickness/2), Vector2(thickness/2, length/2), Vector2(-thickness/2, length/2), Vector2(-thickness/2, thickness/2), Vector2(-length/2, thickness/2), Vector2(-length/2, -thickness/2), Vector2(-thickness/2, -thickness/2), Vector2(-thickness/2, -length/2) ] func get_arrow_points(): var head_width = radius * 0.4 var head_height = radius * 0.5 var tail_width = radius * 0.2 var tail_height = radius * 0.6 return [ Vector2(-tail_width/2, tail_height/2), Vector2(tail_width/2, tail_height/2), Vector2(tail_width/2, 0), Vector2(head_width/2, 0), Vector2(0, -head_height/2), Vector2(-head_width/2, 0), Vector2(-tail_width/2, 0), Vector2(-tail_width/2, tail_height/2) ] func get_house_points(): var base_width = radius * 0.8 var base_height = radius * 0.6 var roof_height = radius * 0.5 return [ Vector2(-base_width/2, base_height/2), Vector2(base_width/2, base_height/2), Vector2(base_width/2, -base_height/2), Vector2(0, -(base_height/2 + roof_height)), Vector2(-base_width/2, -base_height/2), Vector2(-base_width/2, base_height/2) ] func get_umbrella_points(): var result = [] var steps = num_points / 2 var umbrella_radius = radius * 0.7 for i in range(steps + 1): var angle = PI * i / steps result.append(Vector2(cos(angle), sin(angle)) * umbrella_radius) result.append(Vector2(0, umbrella_radius)) result.append(Vector2(0, umbrella_radius * 1.3)) # Mango más largo return result func get_diamond_points(): # Recuerda que en tu match "diamond" llama a get_polygon_points con rotated = true return get_polygon_points(4, true) # Ya debería estar bien con los ajustes de get_polygon_points