Juego de la flecha y empezando a arreglar el juego de seguir la linea

This commit is contained in:
Andrés Moran 2025-04-12 17:51:49 +02:00
parent 4b68f652fe
commit b6f2a0f9af
49 changed files with 625 additions and 53 deletions

4
flecha/.editorconfig Normal file
View File

@ -0,0 +1,4 @@
root = true
[*]
charset = utf-8

1
flecha/.godot/.gdignore Normal file
View File

@ -0,0 +1 @@

View File

@ -0,0 +1,2 @@
Timer
Sprite2D

View File

@ -0,0 +1,63 @@
[docks]
dock_3_selected_tab_idx=0
dock_4_selected_tab_idx=0
dock_5_selected_tab_idx=0
dock_floating={}
dock_filesystem_h_split_offset=240
dock_filesystem_v_split_offset=0
dock_filesystem_display_mode=0
dock_filesystem_file_sort=0
dock_filesystem_file_list_display_mode=1
dock_filesystem_selected_paths=PackedStringArray("res://")
dock_filesystem_uncollapsed_paths=PackedStringArray("Favorites", "res://")
dock_node_current_tab=0
dock_history_include_scene=true
dock_history_include_global=true
dock_bottom=[]
dock_closed=[]
dock_split_2=0
dock_split_3=0
dock_hsplit_1=0
dock_hsplit_2=270
dock_hsplit_3=-270
dock_hsplit_4=0
dock_3="Scene,Import"
dock_4="FileSystem"
dock_5="Inspector,Node,History"
[EditorNode]
open_scenes=PackedStringArray("res://node_2d.tscn")
current_scene="res://node_2d.tscn"
center_split_offset=0
selected_default_debugger_tab_idx=0
selected_main_editor_idx=2
selected_bottom_panel_item=0
[EditorWindow]
screen=0
mode="maximized"
position=Vector2i(0, 23)
[ScriptEditor]
open_scripts=["res://node_2d.gd"]
selected_script="res://node_2d.gd"
open_help=[]
script_split_offset=200
list_split_offset=0
zoom_factor=1.0
[GameView]
floating_window_rect=Rect2i(0, 0, 1932, 1127)
floating_window_screen=0
[ShaderEditor]
open_shaders=[]
split_offset=200
selected_shader=""
text_shader_zoom_factor=1.0

View File

View File

@ -0,0 +1,3 @@
ea4bc82a6ad023ab7ee23ee620429895
::res://::1744467978
icon.svg::CompressedTexture2D::5807478111763404517::1744467965::1744467980::1::::<><><>0<>0<>6a8052f6208c427a34f6f514166b9bac<>res://.godot/imported/icon.svg-218a8f2b3041327d8a5756f3a245f83b.ctex::

View File

@ -0,0 +1,2 @@
res://node_2d.gd
res://node_2d.tscn

View File

@ -0,0 +1,3 @@
[folding]
sections_unfolded=PackedStringArray()

View File

@ -0,0 +1,195 @@
[editor_states]
Anim={
"visible": false
}
2D={
"grid_offset": Vector2(0, 0),
"grid_snap_active": false,
"grid_step": Vector2(8, 8),
"grid_visibility": 1,
"ofs": Vector2(-165, -110),
"primary_grid_step": Vector2i(8, 8),
"show_group_gizmos": true,
"show_guides": true,
"show_helpers": false,
"show_lock_gizmos": true,
"show_origin": true,
"show_position_gizmos": true,
"show_rulers": true,
"show_transformation_gizmos": true,
"show_viewport": true,
"show_zoom_control": true,
"smart_snap_active": false,
"snap_guides": true,
"snap_node_anchors": true,
"snap_node_center": true,
"snap_node_parent": true,
"snap_node_sides": true,
"snap_other_nodes": true,
"snap_pixel": true,
"snap_relative": false,
"snap_rotation": false,
"snap_rotation_offset": 0.0,
"snap_rotation_step": 0.261799,
"snap_scale": false,
"snap_scale_step": 0.1,
"zoom": 1.0
}
3D={
"fov": 70.01,
"gizmos_status": {
"AudioListener3D": 0,
"AudioStreamPlayer3D": 0,
"CPUParticles3D": 0,
"CSGShape3D": 0,
"Camera3D": 0,
"CollisionObject3D": 0,
"CollisionPolygon3D": 0,
"CollisionShape3D": 0,
"Decal": 0,
"FogVolume": 0,
"GPUParticles3D": 0,
"GPUParticlesCollision3D": 0,
"Joint3D": 0,
"Light3D": 0,
"LightmapGI": 0,
"LightmapProbe": 0,
"Marker3D": 0,
"MeshInstance3DCustomAABB": 0,
"NavigationLink3D": 0,
"NavigationObstacle3D": 0,
"NavigationRegion3D": 0,
"OccluderInstance3D": 0,
"Particles3DEmissionShape": 0,
"Path3D": 0,
"PhysicalBone3D": 0,
"RayCast3D": 0,
"ReflectionProbe": 0,
"ShapeCast3D": 0,
"Skeleton3D": 0,
"SoftBody3D": 0,
"SpringArm3D": 0,
"SpringBoneCollision3D": 0,
"SpringBoneSimulator3D": 0,
"VehicleWheel3D": 0,
"VisibleOnScreenNotifier3D": 0,
"VoxelGI": 0
},
"local_coords": false,
"preview_sun_env": {
"environ_ao_enabled": false,
"environ_enabled": true,
"environ_energy": 1.0,
"environ_gi_enabled": false,
"environ_glow_enabled": false,
"environ_ground_color": Color(0.2, 0.169, 0.133, 1),
"environ_sky_color": Color(0.385, 0.454, 0.55, 1),
"environ_tonemap_enabled": true,
"sun_color": Color(1, 1, 1, 1),
"sun_enabled": true,
"sun_energy": 1.0,
"sun_max_distance": 100.0,
"sun_rotation": Vector2(-1.0472, 2.61799)
},
"rotate_snap": 15.0,
"scale_snap": 10.0,
"show_grid": true,
"show_origin": true,
"snap_enabled": false,
"translate_snap": 1.0,
"viewport_mode": 1,
"viewports": [{
"auto_orthogonal": false,
"auto_orthogonal_enabled": true,
"cinematic_preview": false,
"display_mode": 22,
"distance": 4.0,
"doppler": false,
"frame_time": false,
"gizmos": true,
"grid": true,
"half_res": false,
"information": false,
"listener": true,
"lock_rotation": false,
"orthogonal": false,
"position": Vector3(0, 0, 0),
"transform_gizmo": true,
"use_environment": false,
"view_type": 0,
"x_rotation": 0.5,
"y_rotation": -0.5
}, {
"auto_orthogonal": false,
"auto_orthogonal_enabled": true,
"cinematic_preview": false,
"display_mode": 22,
"distance": 4.0,
"doppler": false,
"frame_time": false,
"gizmos": true,
"grid": true,
"half_res": false,
"information": false,
"listener": false,
"lock_rotation": false,
"orthogonal": false,
"position": Vector3(0, 0, 0),
"transform_gizmo": true,
"use_environment": false,
"view_type": 0,
"x_rotation": 0.5,
"y_rotation": -0.5
}, {
"auto_orthogonal": false,
"auto_orthogonal_enabled": true,
"cinematic_preview": false,
"display_mode": 22,
"distance": 4.0,
"doppler": false,
"frame_time": false,
"gizmos": true,
"grid": true,
"half_res": false,
"information": false,
"listener": false,
"lock_rotation": false,
"orthogonal": false,
"position": Vector3(0, 0, 0),
"transform_gizmo": true,
"use_environment": false,
"view_type": 0,
"x_rotation": 0.5,
"y_rotation": -0.5
}, {
"auto_orthogonal": false,
"auto_orthogonal_enabled": true,
"cinematic_preview": false,
"display_mode": 22,
"distance": 4.0,
"doppler": false,
"frame_time": false,
"gizmos": true,
"grid": true,
"half_res": false,
"information": false,
"listener": false,
"lock_rotation": false,
"orthogonal": false,
"position": Vector3(0, 0, 0),
"transform_gizmo": true,
"use_environment": false,
"view_type": 0,
"x_rotation": 0.5,
"y_rotation": -0.5
}],
"zfar": 4000.01,
"znear": 0.05
}
Game={
"camera_override_mode": 2,
"hide_selection": false,
"select_mode": 0
}
selected_nodes=Array[NodePath]([])

View File

@ -0,0 +1,5 @@
[folding]
node_unfolds=[]
resource_unfolds=[]
nodes_folded=[]

View File

@ -0,0 +1,17 @@
[editor_metadata]
executable_path="C:/Users/moran/Downloads/Godot_v4.4.1-stable_win64.exe/Godot_v4.4.1-stable_win64.exe"
[dialog_bounds]
create_new_node=Rect2(510, 190, 900, 700)
project_settings=Rect2(360, 190, 1200, 700)
[script_setup]
last_selected_language="GDScript"
[recent_files]
scripts=["res://node_2d.gd"]
scenes=["res://node_2d.tscn"]

View File

@ -0,0 +1 @@
res://

View File

@ -0,0 +1,13 @@
[res://node_2d.gd]
state={
"bookmarks": PackedInt32Array(),
"breakpoints": PackedInt32Array(),
"column": 15,
"folded_lines": Array[int]([]),
"h_scroll_position": 0,
"row": 14,
"scroll_position": 0.0,
"selection": false,
"syntax_highlighter": "GDScript"
}

View File

@ -0,0 +1 @@
list=[]

View File

@ -0,0 +1,3 @@
source_md5="0eed98577cbbf02f0bdc0f5c9f70465b"
dest_md5="b48bef1f2eefdd190e0a3e60a6188d75"

View File

BIN
flecha/.godot/uid_cache.bin Normal file

Binary file not shown.

1
flecha/icon.svg Normal file
View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="128" height="128"><rect width="124" height="124" x="2" y="2" fill="#363d52" stroke="#212532" stroke-width="4" rx="14"/><g fill="#fff" transform="translate(12.322 12.322)scale(.101)"><path d="M105 673v33q407 354 814 0v-33z"/><path fill="#478cbf" d="m105 673 152 14q12 1 15 14l4 67 132 10 8-61q2-11 15-15h162q13 4 15 15l8 61 132-10 4-67q3-13 15-14l152-14V427q30-39 56-81-35-59-83-108-43 20-82 47-40-37-88-64 7-51 8-102-59-28-123-42-26 43-46 89-49-7-98 0-20-46-46-89-64 14-123 42 1 51 8 102-48 27-88 64-39-27-82-47-48 49-83 108 26 42 56 81zm0 33v39c0 276 813 276 814 0v-39l-134 12-5 69q-2 10-14 13l-162 11q-12 0-16-11l-10-65H446l-10 65q-4 11-16 11l-162-11q-12-3-14-13l-5-69z"/><path d="M483 600c0 34 58 34 58 0v-86c0-34-58-34-58 0z"/><circle cx="725" cy="526" r="90"/><circle cx="299" cy="526" r="90"/></g><g fill="#414042" transform="translate(12.322 12.322)scale(.101)"><circle cx="307" cy="532" r="60"/><circle cx="717" cy="532" r="60"/></g></svg>

After

Width:  |  Height:  |  Size: 994 B

37
flecha/icon.svg.import Normal file
View File

@ -0,0 +1,37 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://co0gk0k0wnlnx"
path="res://.godot/imported/icon.svg-218a8f2b3041327d8a5756f3a245f83b.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://icon.svg"
dest_files=["res://.godot/imported/icon.svg-218a8f2b3041327d8a5756f3a245f83b.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1
svg/scale=1.0
editor/scale_with_editor_scale=false
editor/convert_colors_with_editor_theme=false

77
flecha/node_2d.gd Normal file
View File

@ -0,0 +1,77 @@
extends Node2D
@export var direction_count := 4 # 2, 4, u 8 direcciones
@export var interval := 5.0 # Tiempo entre giros
@export var margin_ratio := 0.1 # Margen visual
var directions: Array[int] = []
var arrow: Polygon2D
var timer: Timer
var last_angle: int = -1 # Última dirección usada (inicial -1 para que no se repita)
func _ready():
get_viewport().connect("size_changed", Callable(self, "_on_viewport_resized"))
# Crear flecha
arrow = Polygon2D.new()
add_child(arrow)
arrow.polygon = _generate_arrow_shape()
arrow.color = Color.DARK_RED
_update_arrow_transform()
# Crear y configurar el temporizador
timer = Timer.new()
timer.wait_time = interval
timer.autostart = true
timer.one_shot = false
add_child(timer)
timer.connect("timeout", Callable(self, "_on_timer_timeout"))
# Configurar posibles direcciones
_set_possible_directions()
change_direction()
func _generate_arrow_shape() -> PackedVector2Array:
return [
Vector2(0, -1),
Vector2(0.4, 0.4),
Vector2(0.2, 0.4),
Vector2(0.2, 1),
Vector2(-0.2, 1),
Vector2(-0.2, 0.4),
Vector2(-0.4, 0.4),
]
func _update_arrow_transform():
var screen_size = get_viewport().get_visible_rect().size
var min_dim = min(screen_size.x, screen_size.y)
var usable_space = min_dim * (1.0 - margin_ratio * 2)
arrow.scale = Vector2(usable_space / 2, usable_space / 2)
arrow.position = screen_size / 2
func _on_viewport_resized():
_update_arrow_transform()
func _set_possible_directions():
match direction_count:
2:
directions = [0, 180]
4:
directions = [0, 90, 180, 270]
8:
directions = [0, 45, 90, 135, 180, 225, 270, 315]
_:
directions = [0, 180]
func change_direction():
var possible = directions.duplicate()
if last_angle != -1 and possible.size() > 1:
possible.erase(last_angle)
var angle = possible[randi() % possible.size()]
last_angle = angle
arrow.rotation_degrees = angle
func _on_timer_timeout():
change_direction()

1
flecha/node_2d.gd.uid Normal file
View File

@ -0,0 +1 @@
uid://dlc5nmf2nugla

6
flecha/node_2d.tscn Normal file
View File

@ -0,0 +1,6 @@
[gd_scene load_steps=2 format=3 uid="uid://cetov1c7e36bf"]
[ext_resource type="Script" uid="uid://dlc5nmf2nugla" path="res://node_2d.gd" id="1_wtcfe"]
[node name="Node2D" type="Node2D"]
script = ExtResource("1_wtcfe")

26
flecha/project.godot Normal file
View File

@ -0,0 +1,26 @@
; Engine configuration file.
; It's best edited using the editor UI and not directly,
; since the parameters that go here are not all obvious.
;
; Format:
; [section] ; section goes between []
; param=value ; assign values to parameters
config_version=5
[application]
config/name="Flecha"
run/main_scene="uid://cetov1c7e36bf"
config/features=PackedStringArray("4.4", "GL Compatibility")
config/icon="res://icon.svg"
[display]
window/size/viewport_width=1920
window/size/viewport_height=1080
[rendering]
renderer/rendering_method="gl_compatibility"
renderer/rendering_method.mobile="gl_compatibility"

View File

@ -192,4 +192,4 @@ Game={
"hide_selection": false,
"select_mode": 0
}
selected_nodes=Array[NodePath]([NodePath("/root/@EditorNode@21272/@Panel@14/@VBoxContainer@15/DockHSplitLeftL/DockHSplitLeftR/DockHSplitMain/@VBoxContainer@26/DockVSplitCenter/@VSplitContainer@54/@VBoxContainer@55/@EditorMainScreen@102/MainScreen/@CanvasItemEditor@11482/@VSplitContainer@11134/@HSplitContainer@11136/@HSplitContainer@11138/@Control@11139/@SubViewportContainer@11140/@SubViewport@11141/Main/VBoxContainer")])
selected_nodes=Array[NodePath]([])

View File

@ -1,5 +1,5 @@
[folding]
node_unfolds=[NodePath("Shape"), PackedStringArray("Visibility", "Transform")]
node_unfolds=[]
resource_unfolds=[]
nodes_folded=[NodePath("MenuButton")]
nodes_folded=[]

View File

@ -192,4 +192,4 @@ Game={
"hide_selection": false,
"select_mode": 0
}
selected_nodes=Array[NodePath]([NodePath("/root/@EditorNode@21272/@Panel@14/@VBoxContainer@15/DockHSplitLeftL/DockHSplitLeftR/DockHSplitMain/@VBoxContainer@26/DockVSplitCenter/@VSplitContainer@54/@VBoxContainer@55/@EditorMainScreen@102/MainScreen/@CanvasItemEditor@11482/@VSplitContainer@11134/@HSplitContainer@11136/@HSplitContainer@11138/@Control@11139/@SubViewportContainer@11140/@SubViewport@11141/Main/VBoxContainer")])
selected_nodes=Array[NodePath]([])

View File

@ -1,3 +1,5 @@
Line2D
Node2D
TextureRect
Label
BoxContainer
@ -10,5 +12,3 @@ AudioStreamPlayer
Node
CheckButton
OptionButton
HSlider
ColorPickerButton

View File

@ -45,11 +45,11 @@ size=Vector2i(1024, 1000)
[ScriptEditor]
open_scripts=["res://circulo_dibujado.gd", "res://game.gd", "res://main.gd", "res://Screen_manager.gd", "res://text_box.gd"]
selected_script="res://main.gd"
selected_script="res://game.gd"
open_help=[]
script_split_offset=243
list_split_offset=0
zoom_factor=1.0
zoom_factor=0.928571
[GameView]

View File

@ -1,5 +1,5 @@
fc8a56933c4b1c8d796fdb8f7a9f9475
::res://::1744315242
::res://::1744470359
banner seguir la línea.PNG::CompressedTexture2D/CompressedTexture2D::2138696205684449453::1744193294::1744193295::1::::<><><>0<>0<>c81335d8132b64696edaae0d3e34b2a7<>res://.godot/imported/banner seguir la línea.PNG-aa4912a02e76f08951bd4fb055564167.ctex::
circulo_dibujado.gd::GDScript/GDScript::8474484448996869988::1744188136::0::1::::<>Node2D<><>0<>0<><>::
export_presets.cfg::TextFile/TextFile::-1::1744194992::0::1::::<><><>0<>0<><>::

View File

@ -0,0 +1,4 @@
res://GameScene.tscn
res://game.gd
res://Main.tscn
res://TextBox.tscn

View File

@ -1,4 +1,3 @@
C:/Users/moran/Documents/2_DAM/Proyecto final/App-Residencia/seguir-la-linea
res://
C:/Program Files/Java/jdk-24
C:/Users/moran/.jdks/openjdk-23.0.1

View File

@ -31,16 +31,12 @@ state={
state={
"bookmarks": PackedInt32Array(),
"breakpoints": PackedInt32Array(),
"column": 50,
"column": 0,
"folded_lines": Array[int]([]),
"h_scroll_position": 0,
"row": 67,
"scroll_position": 63.0,
"selection": true,
"selection_from_column": 50,
"selection_from_line": 67,
"selection_to_column": 63,
"selection_to_line": 67,
"row": 26,
"scroll_position": 14.0,
"selection": false,
"syntax_highlighter": "GDScript"
}
@ -49,10 +45,10 @@ state={
state={
"bookmarks": PackedInt32Array(),
"breakpoints": PackedInt32Array(),
"column": 32,
"column": 48,
"folded_lines": Array[int]([]),
"h_scroll_position": 0,
"row": 13,
"row": 22,
"scroll_position": 0.0,
"selection": false,
"syntax_highlighter": "GDScript"

View File

@ -1,3 +1,3 @@
res://Main.tscn::74398634372fbce7024b196b45ce6dab::1744194971::res://.godot/exported/133200997/export-bcb0d2eb5949c52b6a65bfe9de3e985b-Main.scn
res://GameScene.tscn::adf6b3874ba248afddca90d5779b1d1f::1744194315::res://.godot/exported/133200997/export-e2c04f88cc384ae305072b7c73076002-GameScene.scn
res://TextBox.tscn::ea16bff88c671cad5c68dc2b462ab5b9::1744194315::res://.godot/exported/133200997/export-e6a7070c3a999e756c325a4044202cff-TextBox.scn
res://Main.tscn::74398634372fbce7024b196b45ce6dab::1744472097::res://.godot/exported/133200997/export-bcb0d2eb5949c52b6a65bfe9de3e985b-Main.scn
res://GameScene.tscn::ce479017845964dfcbf4c2c1c75065d8::1744472097::res://.godot/exported/133200997/export-e2c04f88cc384ae305072b7c73076002-GameScene.scn
res://TextBox.tscn::ea16bff88c671cad5c68dc2b462ab5b9::1744472097::res://.godot/exported/133200997/export-e6a7070c3a999e756c325a4044202cff-TextBox.scn

View File

@ -1,22 +1,10 @@
[gd_scene load_steps=4 format=3 uid="uid://kyrpsg085djf"]
[gd_scene load_steps=2 format=3 uid="uid://kyrpsg085djf"]
[ext_resource type="Script" uid="uid://cf24sqa5714px" path="res://game.gd" id="1_haeiw"]
[ext_resource type="Script" uid="uid://ds0drx8caitrw" path="res://circulo_dibujado.gd" id="2_b5kf5"]
[ext_resource type="AudioStream" uid="uid://cwudtop42vbi8" path="res://luvvoice.com-20250407-SAuUo3.mp3" id="3_hvuor"]
[node name="Game" type="Node2D"]
script = ExtResource("1_haeiw")
[node name="Shape" type="Node2D" parent="."]
script = ExtResource("2_b5kf5")
[node name="ShapeLine" type="Line2D" parent="."]
[node name="AudioStreamPlayer" type="AudioStreamPlayer" parent="."]
stream = ExtResource("3_hvuor")
[node name="MenuButton" type="MenuButton" parent="."]
offset_left = 21.0
offset_top = 15.0
offset_right = 262.0
offset_bottom = 90.0
text = "OPCIONES"
flat = false
[node name="ProgressLine" type="Line2D" parent="."]

Binary file not shown.

View File

@ -1,19 +1,143 @@
extends Node2D
@onready var audio_player = $AudioStreamPlayer
@export var bg_color: Color = Color(1, 1, 1, 1)
@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():
RenderingServer.set_default_clear_color(bg_color)
get_viewport().connect("size_changed", Callable(self, "_on_viewport_resized"))
_create_shape_presets()
_draw_selected_shape()
audio_player.play()
$MenuButton.get_popup().add_item("Reproducir sonido", 0)
$MenuButton.get_popup().add_item("Salir", 1)
$MenuButton.get_popup().connect("id_pressed", self._on_menu_item_selected)
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
func _on_menu_item_selected(id):
match id:
0:
$AudioStreamPlayer.play()
1:
ScreenManager.go_back_to_previous_scene()
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

View File

@ -11,7 +11,7 @@ config_version=5
[application]
config/name="Seguir la linea"
run/main_scene="uid://cqv0qxebb6ago"
run/main_scene="uid://kyrpsg085djf"
config/features=PackedStringArray("4.4", "GL Compatibility")
config/icon="res://icon.svg"