AppResidencia/seguir-la-linea/circulo_dibujado.gd

262 lines
8.7 KiB
GDScript

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