From e02fbeddc87bae1ddc8e65a810ef80f9d6b1dd31 Mon Sep 17 00:00:00 2001 From: Kellan KOZUME Date: Sun, 26 Apr 2026 03:25:02 -0400 Subject: [PATCH] refactor(minigame): replace grid with wire-connecting minigame - Replace GridContainer-based puzzle with drag-and-drop wire system - Add draw_wires() and on_canvas_input() driven by WireCanvas node - Shuffle right-side endpoints for varied puzzle layout - Fix type inference errors (Dictionary values cast to Array/Color) - Fix WireCanvas size_flags_vertical to SIZE_SHRINK_CENTER - Set Panel custom_minimum_size and VBox to prevent layout overflow - Title and StatusLabel now always visible --- assets/sprites/scraps_09.png | Bin 0 -> 7714 bytes assets/sprites/scraps_09.png.import | 40 ++ autoloads/audio_manager.gd | 2 + entities/player/player.gd | 2 +- entities/player/player.tscn | 622 +++++++--------------------- ui/minigame/repair_minigame.gd | 283 +++++-------- ui/minigame/repair_minigame.tscn | 26 +- ui/minigame/wire_canvas.gd | 12 + ui/minigame/wire_canvas.gd.uid | 1 + ui/minigame/wire_canvas.tscn | 8 + 10 files changed, 346 insertions(+), 650 deletions(-) create mode 100755 assets/sprites/scraps_09.png create mode 100644 assets/sprites/scraps_09.png.import create mode 100644 ui/minigame/wire_canvas.gd create mode 100644 ui/minigame/wire_canvas.gd.uid create mode 100644 ui/minigame/wire_canvas.tscn diff --git a/assets/sprites/scraps_09.png b/assets/sprites/scraps_09.png new file mode 100755 index 0000000000000000000000000000000000000000..d1d53c552b188ed22014b33f8019ebb4a7930580 GIT binary patch literal 7714 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 Ts;$ItzkrUWzDC&{tHA#Q4oI}9 literal 0 HcmV?d00001 diff --git a/assets/sprites/scraps_09.png.import b/assets/sprites/scraps_09.png.import new file mode 100644 index 0000000..d9ae5dc --- /dev/null +++ b/assets/sprites/scraps_09.png.import @@ -0,0 +1,40 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://dxni3dw1x4lrl" +path="res://.godot/imported/scraps_09.png-83f98d86ccb89d700aeea74833a44455.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://assets/sprites/scraps_09.png" +dest_files=["res://.godot/imported/scraps_09.png-83f98d86ccb89d700aeea74833a44455.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +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/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +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 diff --git a/autoloads/audio_manager.gd b/autoloads/audio_manager.gd index 20b3116..1e9dd56 100644 --- a/autoloads/audio_manager.gd +++ b/autoloads/audio_manager.gd @@ -4,6 +4,7 @@ var music_player : AudioStreamPlayer var sfx_player : AudioStreamPlayer const AMBIANCE_VOLUME_DB := -12.0 +const SFX_VOLUME_DB := -8.0 const AMBIANCES := { "entrepot": preload("res://assets/audio/music/entrepot.ogg"), @@ -31,6 +32,7 @@ func _ready() -> void: sfx_player = AudioStreamPlayer.new() sfx_player.name = "SfxPlayer" sfx_player.bus = "SFX" + sfx_player.volume_db = SFX_VOLUME_DB add_child(sfx_player) sfx_player.process_mode = Node.PROCESS_MODE_ALWAYS diff --git a/entities/player/player.gd b/entities/player/player.gd index 66aecb1..c770869 100644 --- a/entities/player/player.gd +++ b/entities/player/player.gd @@ -1,6 +1,6 @@ extends CharacterBody2D -const SPEED := 120 +const SPEED := 64 const TILE_SIZE := 16 @onready var sprite := $AnimatedSprite2D diff --git a/entities/player/player.tscn b/entities/player/player.tscn index ac3658f..de672fb 100644 --- a/entities/player/player.tscn +++ b/entities/player/player.tscn @@ -1,281 +1,178 @@ [gd_scene format=3 uid="uid://mh3msmluve7p"] [ext_resource type="Script" uid="uid://tuwu6hmfun0e" path="res://entities/player/player.gd" id="1_fkugw"] -[ext_resource type="Texture2D" uid="uid://dhmrfo4dfhbww" path="res://tests/assets/sprites/player_001/IDLE/idle_down.png" id="2_bectd"] -[ext_resource type="Texture2D" uid="uid://byy4h3q72guaj" path="res://tests/assets/sprites/player_001/IDLE/idle_left.png" id="3_wvtmh"] -[ext_resource type="Texture2D" uid="uid://bsdcjceiotf2y" path="res://tests/assets/sprites/player_001/IDLE/idle_right.png" id="4_7thud"] -[ext_resource type="Texture2D" uid="uid://3q718xogyij0" path="res://tests/assets/sprites/player_001/IDLE/idle_up.png" id="5_a1qjk"] -[ext_resource type="Texture2D" uid="uid://bx3l0csay8b8b" path="res://tests/assets/sprites/player_001/RUN/run_down.png" id="6_j3ovn"] -[ext_resource type="Texture2D" uid="uid://ctx7kmb6730oe" path="res://tests/assets/sprites/player_001/RUN/run_left.png" id="7_afbqv"] -[ext_resource type="Texture2D" uid="uid://saic6hvcajw0" path="res://tests/assets/sprites/player_001/RUN/run_right.png" id="8_gx6sm"] -[ext_resource type="Texture2D" uid="uid://dmijbmqm1ysft" path="res://tests/assets/sprites/player_001/RUN/run_up.png" id="9_yqrof"] +[ext_resource type="Texture2D" uid="uid://dxni3dw1x4lrl" path="res://assets/sprites/scraps_09.png" id="2_bectd"] [sub_resource type="CapsuleShape2D" id="CapsuleShape2D_26q78"] -radius = 6.0 -height = 12.0 +radius = 7.0 +height = 14.0 + +[sub_resource type="AtlasTexture" id="AtlasTexture_wvtmh"] +atlas = ExtResource("2_bectd") +region = Rect2(0, 0, 64, 64) + +[sub_resource type="AtlasTexture" id="AtlasTexture_abrql"] +atlas = ExtResource("2_bectd") +region = Rect2(0, 192, 64, 64) + +[sub_resource type="AtlasTexture" id="AtlasTexture_sglur"] +atlas = ExtResource("2_bectd") +region = Rect2(0, 128, 64, 64) + +[sub_resource type="AtlasTexture" id="AtlasTexture_bls4j"] +atlas = ExtResource("2_bectd") +region = Rect2(0, 64, 64, 64) + +[sub_resource type="AtlasTexture" id="AtlasTexture_fkugw"] +atlas = ExtResource("2_bectd") +region = Rect2(0, 0, 64, 64) + +[sub_resource type="AtlasTexture" id="AtlasTexture_8fjmc"] +atlas = ExtResource("2_bectd") +region = Rect2(64, 0, 64, 64) + +[sub_resource type="AtlasTexture" id="AtlasTexture_qiwj3"] +atlas = ExtResource("2_bectd") +region = Rect2(128, 0, 64, 64) + +[sub_resource type="AtlasTexture" id="AtlasTexture_26q78"] +atlas = ExtResource("2_bectd") +region = Rect2(192, 0, 64, 64) + +[sub_resource type="AtlasTexture" id="AtlasTexture_bectd"] +atlas = ExtResource("2_bectd") +region = Rect2(0, 192, 64, 64) + +[sub_resource type="AtlasTexture" id="AtlasTexture_7thud"] +atlas = ExtResource("2_bectd") +region = Rect2(64, 192, 64, 64) + +[sub_resource type="AtlasTexture" id="AtlasTexture_a1qjk"] +atlas = ExtResource("2_bectd") +region = Rect2(128, 192, 64, 64) + +[sub_resource type="AtlasTexture" id="AtlasTexture_j3ovn"] +atlas = ExtResource("2_bectd") +region = Rect2(192, 192, 64, 64) + +[sub_resource type="AtlasTexture" id="AtlasTexture_afbqv"] +atlas = ExtResource("2_bectd") +region = Rect2(0, 128, 64, 64) + +[sub_resource type="AtlasTexture" id="AtlasTexture_gx6sm"] +atlas = ExtResource("2_bectd") +region = Rect2(64, 128, 64, 64) + +[sub_resource type="AtlasTexture" id="AtlasTexture_yqrof"] +atlas = ExtResource("2_bectd") +region = Rect2(128, 128, 64, 64) [sub_resource type="AtlasTexture" id="AtlasTexture_3wlsy"] atlas = ExtResource("2_bectd") -region = Rect2(0, 0, 96, 80) +region = Rect2(192, 128, 64, 64) [sub_resource type="AtlasTexture" id="AtlasTexture_b2kln"] atlas = ExtResource("2_bectd") -region = Rect2(96, 0, 96, 80) +region = Rect2(0, 64, 64, 64) [sub_resource type="AtlasTexture" id="AtlasTexture_we0b7"] atlas = ExtResource("2_bectd") -region = Rect2(192, 0, 96, 80) +region = Rect2(64, 64, 64, 64) [sub_resource type="AtlasTexture" id="AtlasTexture_mtric"] atlas = ExtResource("2_bectd") -region = Rect2(288, 0, 96, 80) +region = Rect2(128, 64, 64, 64) [sub_resource type="AtlasTexture" id="AtlasTexture_eyb6c"] atlas = ExtResource("2_bectd") -region = Rect2(384, 0, 96, 80) - -[sub_resource type="AtlasTexture" id="AtlasTexture_221hk"] -atlas = ExtResource("2_bectd") -region = Rect2(480, 0, 96, 80) - -[sub_resource type="AtlasTexture" id="AtlasTexture_ghoj8"] -atlas = ExtResource("2_bectd") -region = Rect2(576, 0, 96, 80) - -[sub_resource type="AtlasTexture" id="AtlasTexture_t1t22"] -atlas = ExtResource("2_bectd") -region = Rect2(672, 0, 96, 80) - -[sub_resource type="AtlasTexture" id="AtlasTexture_50fht"] -atlas = ExtResource("3_wvtmh") -region = Rect2(0, 0, 96, 80) - -[sub_resource type="AtlasTexture" id="AtlasTexture_wuv6x"] -atlas = ExtResource("3_wvtmh") -region = Rect2(96, 0, 96, 80) - -[sub_resource type="AtlasTexture" id="AtlasTexture_qpopc"] -atlas = ExtResource("3_wvtmh") -region = Rect2(192, 0, 96, 80) - -[sub_resource type="AtlasTexture" id="AtlasTexture_wq0jh"] -atlas = ExtResource("3_wvtmh") -region = Rect2(288, 0, 96, 80) - -[sub_resource type="AtlasTexture" id="AtlasTexture_gt4e4"] -atlas = ExtResource("3_wvtmh") -region = Rect2(384, 0, 96, 80) - -[sub_resource type="AtlasTexture" id="AtlasTexture_24ehl"] -atlas = ExtResource("3_wvtmh") -region = Rect2(480, 0, 96, 80) - -[sub_resource type="AtlasTexture" id="AtlasTexture_bwdx1"] -atlas = ExtResource("3_wvtmh") -region = Rect2(576, 0, 96, 80) - -[sub_resource type="AtlasTexture" id="AtlasTexture_vewsg"] -atlas = ExtResource("3_wvtmh") -region = Rect2(672, 0, 96, 80) - -[sub_resource type="AtlasTexture" id="AtlasTexture_2soq1"] -atlas = ExtResource("4_7thud") -region = Rect2(0, 0, 96, 80) - -[sub_resource type="AtlasTexture" id="AtlasTexture_8q4fm"] -atlas = ExtResource("4_7thud") -region = Rect2(96, 0, 96, 80) - -[sub_resource type="AtlasTexture" id="AtlasTexture_np63p"] -atlas = ExtResource("4_7thud") -region = Rect2(192, 0, 96, 80) - -[sub_resource type="AtlasTexture" id="AtlasTexture_0eo6o"] -atlas = ExtResource("4_7thud") -region = Rect2(288, 0, 96, 80) - -[sub_resource type="AtlasTexture" id="AtlasTexture_ttr27"] -atlas = ExtResource("4_7thud") -region = Rect2(384, 0, 96, 80) - -[sub_resource type="AtlasTexture" id="AtlasTexture_13wue"] -atlas = ExtResource("4_7thud") -region = Rect2(480, 0, 96, 80) - -[sub_resource type="AtlasTexture" id="AtlasTexture_wy7bt"] -atlas = ExtResource("4_7thud") -region = Rect2(576, 0, 96, 80) - -[sub_resource type="AtlasTexture" id="AtlasTexture_geky7"] -atlas = ExtResource("4_7thud") -region = Rect2(672, 0, 96, 80) - -[sub_resource type="AtlasTexture" id="AtlasTexture_qwspa"] -atlas = ExtResource("5_a1qjk") -region = Rect2(0, 0, 96, 80) - -[sub_resource type="AtlasTexture" id="AtlasTexture_r633c"] -atlas = ExtResource("5_a1qjk") -region = Rect2(96, 0, 96, 80) - -[sub_resource type="AtlasTexture" id="AtlasTexture_pacje"] -atlas = ExtResource("5_a1qjk") -region = Rect2(192, 0, 96, 80) - -[sub_resource type="AtlasTexture" id="AtlasTexture_2h0qb"] -atlas = ExtResource("5_a1qjk") -region = Rect2(288, 0, 96, 80) - -[sub_resource type="AtlasTexture" id="AtlasTexture_mmk7k"] -atlas = ExtResource("5_a1qjk") -region = Rect2(384, 0, 96, 80) - -[sub_resource type="AtlasTexture" id="AtlasTexture_g3pa7"] -atlas = ExtResource("5_a1qjk") -region = Rect2(480, 0, 96, 80) - -[sub_resource type="AtlasTexture" id="AtlasTexture_7otdo"] -atlas = ExtResource("5_a1qjk") -region = Rect2(576, 0, 96, 80) - -[sub_resource type="AtlasTexture" id="AtlasTexture_c112w"] -atlas = ExtResource("5_a1qjk") -region = Rect2(672, 0, 96, 80) - -[sub_resource type="AtlasTexture" id="AtlasTexture_u37te"] -atlas = ExtResource("6_j3ovn") -region = Rect2(0, 0, 96, 80) - -[sub_resource type="AtlasTexture" id="AtlasTexture_ssgi7"] -atlas = ExtResource("6_j3ovn") -region = Rect2(96, 0, 96, 80) - -[sub_resource type="AtlasTexture" id="AtlasTexture_rtlkk"] -atlas = ExtResource("6_j3ovn") -region = Rect2(192, 0, 96, 80) - -[sub_resource type="AtlasTexture" id="AtlasTexture_a2brg"] -atlas = ExtResource("6_j3ovn") -region = Rect2(288, 0, 96, 80) - -[sub_resource type="AtlasTexture" id="AtlasTexture_arp52"] -atlas = ExtResource("6_j3ovn") -region = Rect2(384, 0, 96, 80) - -[sub_resource type="AtlasTexture" id="AtlasTexture_jjk8f"] -atlas = ExtResource("6_j3ovn") -region = Rect2(480, 0, 96, 80) - -[sub_resource type="AtlasTexture" id="AtlasTexture_cnswy"] -atlas = ExtResource("6_j3ovn") -region = Rect2(576, 0, 96, 80) - -[sub_resource type="AtlasTexture" id="AtlasTexture_q5bfg"] -atlas = ExtResource("6_j3ovn") -region = Rect2(672, 0, 96, 80) - -[sub_resource type="AtlasTexture" id="AtlasTexture_p22ii"] -atlas = ExtResource("7_afbqv") -region = Rect2(0, 0, 96, 80) - -[sub_resource type="AtlasTexture" id="AtlasTexture_7rgwd"] -atlas = ExtResource("7_afbqv") -region = Rect2(96, 0, 96, 80) - -[sub_resource type="AtlasTexture" id="AtlasTexture_24so6"] -atlas = ExtResource("7_afbqv") -region = Rect2(192, 0, 96, 80) - -[sub_resource type="AtlasTexture" id="AtlasTexture_sk710"] -atlas = ExtResource("7_afbqv") -region = Rect2(288, 0, 96, 80) - -[sub_resource type="AtlasTexture" id="AtlasTexture_kbbq5"] -atlas = ExtResource("7_afbqv") -region = Rect2(384, 0, 96, 80) - -[sub_resource type="AtlasTexture" id="AtlasTexture_akixf"] -atlas = ExtResource("7_afbqv") -region = Rect2(480, 0, 96, 80) - -[sub_resource type="AtlasTexture" id="AtlasTexture_3y563"] -atlas = ExtResource("7_afbqv") -region = Rect2(576, 0, 96, 80) - -[sub_resource type="AtlasTexture" id="AtlasTexture_sgfia"] -atlas = ExtResource("7_afbqv") -region = Rect2(672, 0, 96, 80) - -[sub_resource type="AtlasTexture" id="AtlasTexture_sv458"] -atlas = ExtResource("8_gx6sm") -region = Rect2(0, 0, 96, 80) - -[sub_resource type="AtlasTexture" id="AtlasTexture_pth52"] -atlas = ExtResource("8_gx6sm") -region = Rect2(96, 0, 96, 80) - -[sub_resource type="AtlasTexture" id="AtlasTexture_4iu2e"] -atlas = ExtResource("8_gx6sm") -region = Rect2(192, 0, 96, 80) - -[sub_resource type="AtlasTexture" id="AtlasTexture_0q7bw"] -atlas = ExtResource("8_gx6sm") -region = Rect2(288, 0, 96, 80) - -[sub_resource type="AtlasTexture" id="AtlasTexture_qb5t2"] -atlas = ExtResource("8_gx6sm") -region = Rect2(384, 0, 96, 80) - -[sub_resource type="AtlasTexture" id="AtlasTexture_qsjf6"] -atlas = ExtResource("8_gx6sm") -region = Rect2(480, 0, 96, 80) - -[sub_resource type="AtlasTexture" id="AtlasTexture_k3n4f"] -atlas = ExtResource("8_gx6sm") -region = Rect2(576, 0, 96, 80) - -[sub_resource type="AtlasTexture" id="AtlasTexture_gmffv"] -atlas = ExtResource("8_gx6sm") -region = Rect2(672, 0, 96, 80) - -[sub_resource type="AtlasTexture" id="AtlasTexture_rqau1"] -atlas = ExtResource("9_yqrof") -region = Rect2(0, 0, 96, 80) - -[sub_resource type="AtlasTexture" id="AtlasTexture_gv6fn"] -atlas = ExtResource("9_yqrof") -region = Rect2(96, 0, 96, 80) - -[sub_resource type="AtlasTexture" id="AtlasTexture_2vqvu"] -atlas = ExtResource("9_yqrof") -region = Rect2(192, 0, 96, 80) - -[sub_resource type="AtlasTexture" id="AtlasTexture_yb4xh"] -atlas = ExtResource("9_yqrof") -region = Rect2(288, 0, 96, 80) - -[sub_resource type="AtlasTexture" id="AtlasTexture_ix1gt"] -atlas = ExtResource("9_yqrof") -region = Rect2(384, 0, 96, 80) - -[sub_resource type="AtlasTexture" id="AtlasTexture_sym6v"] -atlas = ExtResource("9_yqrof") -region = Rect2(480, 0, 96, 80) - -[sub_resource type="AtlasTexture" id="AtlasTexture_dnai7"] -atlas = ExtResource("9_yqrof") -region = Rect2(576, 0, 96, 80) - -[sub_resource type="AtlasTexture" id="AtlasTexture_u8til"] -atlas = ExtResource("9_yqrof") -region = Rect2(672, 0, 96, 80) +region = Rect2(192, 64, 64, 64) [sub_resource type="SpriteFrames" id="SpriteFrames_ix1gt"] animations = [{ "frames": [{ "duration": 1.0, -"texture": SubResource("AtlasTexture_3wlsy") +"texture": SubResource("AtlasTexture_wvtmh") +}], +"loop": true, +"name": &"idle_down", +"speed": 10.0 }, { +"frames": [{ +"duration": 1.0, +"texture": SubResource("AtlasTexture_abrql") +}], +"loop": true, +"name": &"idle_left", +"speed": 10.0 +}, { +"frames": [{ +"duration": 1.0, +"texture": SubResource("AtlasTexture_sglur") +}], +"loop": true, +"name": &"idle_right", +"speed": 10.0 +}, { +"frames": [{ +"duration": 1.0, +"texture": SubResource("AtlasTexture_bls4j") +}], +"loop": true, +"name": &"idle_up", +"speed": 10.0 +}, { +"frames": [{ +"duration": 1.0, +"texture": SubResource("AtlasTexture_fkugw") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_8fjmc") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_qiwj3") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_26q78") +}], +"loop": true, +"name": &"walk_down", +"speed": 10.0 +}, { +"frames": [{ +"duration": 1.0, +"texture": SubResource("AtlasTexture_bectd") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_7thud") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_a1qjk") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_j3ovn") +}], +"loop": true, +"name": &"walk_left", +"speed": 10.0 +}, { +"frames": [{ +"duration": 1.0, +"texture": SubResource("AtlasTexture_afbqv") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_gx6sm") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_yqrof") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_3wlsy") +}], +"loop": true, +"name": &"walk_right", +"speed": 10.0 +}, { +"frames": [{ "duration": 1.0, "texture": SubResource("AtlasTexture_b2kln") }, { @@ -287,218 +184,6 @@ animations = [{ }, { "duration": 1.0, "texture": SubResource("AtlasTexture_eyb6c") -}, { -"duration": 1.0, -"texture": SubResource("AtlasTexture_221hk") -}, { -"duration": 1.0, -"texture": SubResource("AtlasTexture_ghoj8") -}, { -"duration": 1.0, -"texture": SubResource("AtlasTexture_t1t22") -}], -"loop": true, -"name": &"idle_down", -"speed": 10.0 -}, { -"frames": [{ -"duration": 1.0, -"texture": SubResource("AtlasTexture_50fht") -}, { -"duration": 1.0, -"texture": SubResource("AtlasTexture_wuv6x") -}, { -"duration": 1.0, -"texture": SubResource("AtlasTexture_qpopc") -}, { -"duration": 1.0, -"texture": SubResource("AtlasTexture_wq0jh") -}, { -"duration": 1.0, -"texture": SubResource("AtlasTexture_gt4e4") -}, { -"duration": 1.0, -"texture": SubResource("AtlasTexture_24ehl") -}, { -"duration": 1.0, -"texture": SubResource("AtlasTexture_bwdx1") -}, { -"duration": 1.0, -"texture": SubResource("AtlasTexture_vewsg") -}], -"loop": true, -"name": &"idle_left", -"speed": 10.0 -}, { -"frames": [{ -"duration": 1.0, -"texture": SubResource("AtlasTexture_2soq1") -}, { -"duration": 1.0, -"texture": SubResource("AtlasTexture_8q4fm") -}, { -"duration": 1.0, -"texture": SubResource("AtlasTexture_np63p") -}, { -"duration": 1.0, -"texture": SubResource("AtlasTexture_0eo6o") -}, { -"duration": 1.0, -"texture": SubResource("AtlasTexture_ttr27") -}, { -"duration": 1.0, -"texture": SubResource("AtlasTexture_13wue") -}, { -"duration": 1.0, -"texture": SubResource("AtlasTexture_wy7bt") -}, { -"duration": 1.0, -"texture": SubResource("AtlasTexture_geky7") -}], -"loop": true, -"name": &"idle_right", -"speed": 10.0 -}, { -"frames": [{ -"duration": 1.0, -"texture": SubResource("AtlasTexture_qwspa") -}, { -"duration": 1.0, -"texture": SubResource("AtlasTexture_r633c") -}, { -"duration": 1.0, -"texture": SubResource("AtlasTexture_pacje") -}, { -"duration": 1.0, -"texture": SubResource("AtlasTexture_2h0qb") -}, { -"duration": 1.0, -"texture": SubResource("AtlasTexture_mmk7k") -}, { -"duration": 1.0, -"texture": SubResource("AtlasTexture_g3pa7") -}, { -"duration": 1.0, -"texture": SubResource("AtlasTexture_7otdo") -}, { -"duration": 1.0, -"texture": SubResource("AtlasTexture_c112w") -}], -"loop": true, -"name": &"idle_up", -"speed": 10.0 -}, { -"frames": [{ -"duration": 1.0, -"texture": SubResource("AtlasTexture_u37te") -}, { -"duration": 1.0, -"texture": SubResource("AtlasTexture_ssgi7") -}, { -"duration": 1.0, -"texture": SubResource("AtlasTexture_rtlkk") -}, { -"duration": 1.0, -"texture": SubResource("AtlasTexture_a2brg") -}, { -"duration": 1.0, -"texture": SubResource("AtlasTexture_arp52") -}, { -"duration": 1.0, -"texture": SubResource("AtlasTexture_jjk8f") -}, { -"duration": 1.0, -"texture": SubResource("AtlasTexture_cnswy") -}, { -"duration": 1.0, -"texture": SubResource("AtlasTexture_q5bfg") -}], -"loop": true, -"name": &"walk_down", -"speed": 10.0 -}, { -"frames": [{ -"duration": 1.0, -"texture": SubResource("AtlasTexture_p22ii") -}, { -"duration": 1.0, -"texture": SubResource("AtlasTexture_7rgwd") -}, { -"duration": 1.0, -"texture": SubResource("AtlasTexture_24so6") -}, { -"duration": 1.0, -"texture": SubResource("AtlasTexture_sk710") -}, { -"duration": 1.0, -"texture": SubResource("AtlasTexture_kbbq5") -}, { -"duration": 1.0, -"texture": SubResource("AtlasTexture_akixf") -}, { -"duration": 1.0, -"texture": SubResource("AtlasTexture_3y563") -}, { -"duration": 1.0, -"texture": SubResource("AtlasTexture_sgfia") -}], -"loop": true, -"name": &"walk_left", -"speed": 10.0 -}, { -"frames": [{ -"duration": 1.0, -"texture": SubResource("AtlasTexture_sv458") -}, { -"duration": 1.0, -"texture": SubResource("AtlasTexture_pth52") -}, { -"duration": 1.0, -"texture": SubResource("AtlasTexture_4iu2e") -}, { -"duration": 1.0, -"texture": SubResource("AtlasTexture_0q7bw") -}, { -"duration": 1.0, -"texture": SubResource("AtlasTexture_qb5t2") -}, { -"duration": 1.0, -"texture": SubResource("AtlasTexture_qsjf6") -}, { -"duration": 1.0, -"texture": SubResource("AtlasTexture_k3n4f") -}, { -"duration": 1.0, -"texture": SubResource("AtlasTexture_gmffv") -}], -"loop": true, -"name": &"walk_right", -"speed": 10.0 -}, { -"frames": [{ -"duration": 1.0, -"texture": SubResource("AtlasTexture_rqau1") -}, { -"duration": 1.0, -"texture": SubResource("AtlasTexture_gv6fn") -}, { -"duration": 1.0, -"texture": SubResource("AtlasTexture_2vqvu") -}, { -"duration": 1.0, -"texture": SubResource("AtlasTexture_yb4xh") -}, { -"duration": 1.0, -"texture": SubResource("AtlasTexture_ix1gt") -}, { -"duration": 1.0, -"texture": SubResource("AtlasTexture_sym6v") -}, { -"duration": 1.0, -"texture": SubResource("AtlasTexture_dnai7") -}, { -"duration": 1.0, -"texture": SubResource("AtlasTexture_u8til") }], "loop": true, "name": &"walk_up", @@ -506,7 +191,7 @@ animations = [{ }] [sub_resource type="RectangleShape2D" id="RectangleShape2D_bectd"] -size = Vector2(45.375, 42.84375) +size = Vector2(65.84375, 66.25) [node name="Player" type="CharacterBody2D" unique_id=1424887591] collision_layer = 2 @@ -521,10 +206,11 @@ zoom = Vector2(0.75, 0.75) position_smoothing_enabled = true [node name="AnimatedSprite2D" type="AnimatedSprite2D" parent="." unique_id=1926532622] -position = Vector2(-1, -8) +position = Vector2(0, -13) sprite_frames = SubResource("SpriteFrames_ix1gt") -animation = &"walk_right" +animation = &"walk_down" autoplay = "idle_down" +frame_progress = 0.9045258 [node name="InteractionArea" type="Area2D" parent="." unique_id=1623204784] position = Vector2(-1, -12) @@ -532,7 +218,7 @@ collision_layer = 16 collision_mask = 28 [node name="CollisionShape2D" type="CollisionShape2D" parent="InteractionArea" unique_id=446150610] -position = Vector2(1, 9) +position = Vector2(1, -2) shape = SubResource("RectangleShape2D_bectd") debug_color = Color(0.9411765, 0, 0.29411766, 0.19607843) diff --git a/ui/minigame/repair_minigame.gd b/ui/minigame/repair_minigame.gd index 9b3f62d..3ed0fcc 100644 --- a/ui/minigame/repair_minigame.gd +++ b/ui/minigame/repair_minigame.gd @@ -6,147 +6,152 @@ signal repair_complete const PUZZLES := { "vrac7": { "title": "RECONNECTION — MOTOR SYSTEM", - "connections": [[0, 0], [1, 2], [3, 3]] + "colors": [Color("#f4c430"), Color("#5bc8f5"), Color("#f47c3c")] }, "iris3": { "title": "RECALIBRATION — OPTICAL SENSOR", - "connections": [[0, 1], [2, 3]] + "colors": [Color("#f4c430"), Color("#5bc8f5")] }, - "scrap09": { + "scrap09": { "title": "SELF-REPAIR — SCRAP-09", - "connections": [[0, 0], [1, 2], [2, 3]] + "colors": [Color("#f4c430"), Color("#5bc8f5"), Color("#f47c3c")] }, } -const GRID_SIZE := 4 +const DOT_RADIUS := 8.0 +const WIRE_WIDTH := 4.0 -var current_puzzle: Dictionary -var paths: Array = [] -var active_path: int = -1 -var solved_paths: Array = [] +var current_puzzle : Dictionary +var right_order : Array = [] +var connections : Dictionary = {} +var dragging : int = -1 +var drag_pos : Vector2 -@onready var grid := $Background/Panel/VBoxContainer/Grid -@onready var title_lbl := $Background/Panel/VBoxContainer/Title -@onready var status := $Background/Panel/VBoxContainer/StatusLabel +@onready var wire_canvas : Control = $Background/Panel/VBoxContainer/WireCanvas +@onready var title_lbl : Label = $Background/Panel/VBoxContainer/Title +@onready var status : Label = $Background/Panel/VBoxContainer/StatusLabel -# ── Lifecycle ───────────────────────────────────────────────────────────────── func _ready() -> void: + var vbox = $Background/Panel/VBoxContainer layer = 1000 - - var panel := $Background/Panel - panel.set_anchors_preset(Control.PRESET_CENTER) - - var vbox := $Background/Panel/VBoxContainer - vbox.alignment = BoxContainer.ALIGNMENT_CENTER - vbox.add_theme_constant_override("separation", 12) - - # Centre la grid horizontalement dans le VBox - grid.size_flags_horizontal = Control.SIZE_SHRINK_CENTER - grid.size_flags_vertical = Control.SIZE_SHRINK_CENTER + wire_canvas.custom_minimum_size = Vector2(320, 120) + wire_canvas.size_flags_vertical = Control.SIZE_SHRINK_CENTER + vbox.size_flags_vertical = Control.SIZE_SHRINK_CENTER func _unhandled_input(event: InputEvent) -> void: if event.is_action_pressed("ui_cancel"): _cancel() -# ── API publique ────────────────────────────────────────────────────────────── - func open(robot_id: String) -> void: - current_puzzle = PUZZLES[robot_id] - title_lbl.text = current_puzzle["title"] - paths.clear() - solved_paths.clear() - for _c in current_puzzle["connections"]: - paths.append([]) - solved_paths.append(false) + current_puzzle = PUZZLES.get(robot_id, {}) + if current_puzzle.is_empty(): + return + title_lbl.text = current_puzzle["title"] as String + connections.clear() + dragging = -1 + + var n: int = (current_puzzle["colors"] as Array).size() # ← FIX ligne 49 + right_order = range(n) + right_order.shuffle() + _set_hud_visible(false) _set_player_enabled(false) - _build_grid() _update_status() + wire_canvas.queue_redraw() show() -# ── Grille ──────────────────────────────────────────────────────────────────── +# ── Drawing ──────────────────────────────────────────────────────────────────── -func _build_grid() -> void: - for child in grid.get_children(): - child.queue_free() - - # Taille fixe de la grille : GRID_SIZE * taille bouton + séparation - var cell_size := 25 - var separation := 4 - var grid_px := GRID_SIZE * cell_size + (GRID_SIZE - 1) * separation - grid.custom_minimum_size = Vector2(grid_px, grid_px) - grid.columns = GRID_SIZE - - for row in GRID_SIZE: - for col in GRID_SIZE: - var btn := Button.new() - btn.custom_minimum_size = Vector2(cell_size, cell_size) - btn.name = "Cell_%d_%d" % [row, col] - btn.add_theme_stylebox_override("normal", _make_stylebox(Color(0.15, 0.15, 0.15), 1.0)) - btn.add_theme_stylebox_override("hover", _make_stylebox(Color(0.25, 0.25, 0.25), 1.0)) - - if col == 0: - var path_idx = _entry_for_row(row) - if path_idx >= 0: - btn.text = "0" - btn.modulate = _color_for_path(path_idx) - elif col == 3: - var path_idx = _exit_for_row(row) - if path_idx >= 0: - btn.text = "X" - btn.modulate = _color_for_path(path_idx) - - btn.pressed.connect(_on_cell_pressed.bind(row, col)) - grid.add_child(btn) - -func _on_cell_pressed(row: int, col: int) -> void: - var entry_idx = _entry_for_row(row) - if col == 0 and entry_idx >= 0: - active_path = entry_idx - paths[active_path] = [Vector2i(row, col)] - _refresh_grid() +func draw_wires(canvas: Control) -> void: + if current_puzzle.is_empty(): return + var colors := current_puzzle["colors"] as Array + var n: int = colors.size() + var w := canvas.size.x + var h := canvas.size.y - if active_path < 0: + canvas.draw_line(Vector2(w * 0.5, 10), Vector2(w * 0.5, h - 10), + Color(1, 1, 1, 0.08), 1.0) + + for left_idx in connections: + var right_slot: int = connections[left_idx] + var from := _left_pos(left_idx, n, w, h) + var to := _right_pos(right_slot, n, w, h) + canvas.draw_line(from, to, colors[left_idx], WIRE_WIDTH, true) + + if dragging >= 0: + var from := _left_pos(dragging, n, w, h) + canvas.draw_line(from, drag_pos, (colors[dragging] as Color).lightened(0.3), WIRE_WIDTH, true) + + for i in n: + var pos := _left_pos(i, n, w, h) + var c := colors[i] as Color + canvas.draw_circle(pos, DOT_RADIUS, c) + if not connections.has(i): + canvas.draw_arc(pos, DOT_RADIUS + 4, 0, TAU, 32, c.lightened(0.5), 2.0) + + for i in n: + var pos := _right_pos(i, n, w, h) + var col_idx : int = right_order[i] + var c := colors[col_idx] as Color + canvas.draw_circle(pos, DOT_RADIUS, c) + if not connections.values().has(i): + canvas.draw_arc(pos, DOT_RADIUS + 4, 0, TAU, 32, c.lightened(0.5), 2.0) + +# ── Input ───────────────────────────────────────────────────────────────────── + +func on_canvas_input(event: InputEvent) -> void: + if current_puzzle.is_empty(): return + var colors := current_puzzle["colors"] as Array + var n: int = colors.size() + var w := wire_canvas.size.x + var h := wire_canvas.size.y - var last: Vector2i = paths[active_path].back() if paths[active_path].size() > 0 else Vector2i(-1, -1) - var cell := Vector2i(row, col) + if event is InputEventMouseButton and event.button_index == MOUSE_BUTTON_LEFT: + if event.pressed: + for i in n: + if event.position.distance_to(_left_pos(i, n, w, h)) <= DOT_RADIUS + 6.0: + connections.erase(i) + dragging = i + drag_pos = event.position + _update_status() + wire_canvas.queue_redraw() + return + else: + if dragging >= 0: + for i in n: + if connections.values().has(i): + continue + if event.position.distance_to(_right_pos(i, n, w, h)) <= DOT_RADIUS + 6.0: + if right_order[i] == dragging: + connections[dragging] = i + _update_status() + _check_win() + dragging = -1 + wire_canvas.queue_redraw() - if not _is_adjacent(last, cell): - return + elif event is InputEventMouseMotion and dragging >= 0: + drag_pos = event.position + wire_canvas.queue_redraw() - for i in paths.size(): - if i == active_path: - continue - if cell in paths[i]: - return +# ── Helpers ─────────────────────────────────────────────────────────────────── - paths[active_path].append(cell) +func _left_pos(i: int, n: int, w: float, h: float) -> Vector2: + return Vector2(DOT_RADIUS + 20.0, h / (n + 1) * (i + 1)) - var exit_row = current_puzzle["connections"][active_path][1] - if col == 3 and row == exit_row: - solved_paths[active_path] = true - active_path = -1 - _refresh_grid() - _update_status() - _check_win() - return - - _refresh_grid() - _update_status() - -# ── Victoire / Annulation ───────────────────────────────────────────────────── +func _right_pos(i: int, n: int, w: float, h: float) -> Vector2: + return Vector2(w - DOT_RADIUS - 20.0, h / (n + 1) * (i + 1)) func _check_win() -> void: - if solved_paths.all(func(s): return s == true): + if connections.size() == (current_puzzle["colors"] as Array).size(): await get_tree().create_timer(0.6).timeout repair_complete.emit() _close() func _cancel() -> void: - active_path = -1 + dragging = -1 _close() func _close() -> void: @@ -154,89 +159,23 @@ func _close() -> void: _set_player_enabled(true) hide() -# ── Affichage ───────────────────────────────────────────────────────────────── - -func _refresh_grid() -> void: - for row in GRID_SIZE: - for col in GRID_SIZE: - var btn: Button = grid.get_node_or_null("Cell_%d_%d" % [row, col]) - if btn == null: - continue - var cell := Vector2i(row, col) - var found := false - - for i in paths.size(): - if cell in paths[i]: - var c := _color_for_path(i) - var is_endpoint := (col == 0 or col == 3) - btn.text = "O" if is_endpoint else "+" - btn.modulate = Color.WHITE - btn.add_theme_stylebox_override("normal", _make_stylebox(c, 0.5)) - btn.add_theme_color_override("font_color", c) - found = true - break - - if not found: - btn.modulate = Color.WHITE - btn.text = "" - btn.add_theme_stylebox_override("normal", _make_stylebox(Color(0.15, 0.15, 0.15), 1.0)) - btn.remove_theme_color_override("font_color") - var ei = _entry_for_row(row) - var xi = _exit_for_row(row) - if col == 0 and ei >= 0: - btn.text = "O" - btn.add_theme_color_override("font_color", _color_for_path(ei)) - elif col == 3 and xi >= 0: - btn.text = "O" - func _update_status() -> void: - var count := solved_paths.count(true) - var total := solved_paths.size() - if count == total: + var total: int = (current_puzzle.get("colors", []) as Array).size() + var done := connections.size() + if done == total: status.text = "REPAIR COMPLETE" status.add_theme_color_override("font_color", Color("#6daa45")) else: - status.text = "%d / %d connections established" % [count, total] + status.text = "%d / %d connections established" % [done, total] status.remove_theme_color_override("font_color") -# ── Helpers ─────────────────────────────────────────────────────────────────── - -func _set_hud_visible(visible: bool) -> void: +func _set_hud_visible(v: bool) -> void: var hud = get_tree().get_first_node_in_group("hud") if hud: - hud.visible = visible - -func _make_stylebox(color: Color, alpha: float) -> StyleBoxFlat: - var sb := StyleBoxFlat.new() - sb.bg_color = Color(color.r, color.g, color.b, alpha) - sb.corner_radius_top_left = 4 - sb.corner_radius_top_right = 4 - sb.corner_radius_bottom_left = 4 - sb.corner_radius_bottom_right = 4 - return sb - -func _entry_for_row(row: int) -> int: - for i in current_puzzle["connections"].size(): - if current_puzzle["connections"][i][0] == row: - return i - return -1 - -func _exit_for_row(row: int) -> int: - for i in current_puzzle["connections"].size(): - if current_puzzle["connections"][i][1] == row: - return i - return -1 - -func _is_adjacent(a: Vector2i, b: Vector2i) -> bool: - return abs(a.x - b.x) + abs(a.y - b.y) == 1 - -func _color_for_path(idx: int) -> Color: - var colors := [Color("#f4c430"), Color("#5bc8f5"), Color("#f47c3c")] - return colors[idx % colors.size()] + hud.visible = v func _set_player_enabled(enabled: bool) -> void: var player = get_tree().get_first_node_in_group("player") - print("_set_player_enabled: ", enabled, " | player trouvé: ", player) if player: player.set_process(enabled) player.set_physics_process(enabled) diff --git a/ui/minigame/repair_minigame.tscn b/ui/minigame/repair_minigame.tscn index eb811fe..1525a1c 100644 --- a/ui/minigame/repair_minigame.tscn +++ b/ui/minigame/repair_minigame.tscn @@ -1,6 +1,7 @@ [gd_scene format=3 uid="uid://djtxltf8mtuv6"] [ext_resource type="Script" uid="uid://b5237vkobhji0" path="res://ui/minigame/repair_minigame.gd" id="1_151ia"] +[ext_resource type="PackedScene" uid="uid://dchwkw273wjq7" path="res://ui/minigame/wire_canvas.tscn" id="2_sehdy"] [node name="RepairMinigame" type="CanvasLayer" unique_id=189116174] script = ExtResource("1_151ia") @@ -11,18 +12,23 @@ anchor_left = 0.5 anchor_top = 0.5 anchor_right = 0.5 anchor_bottom = 0.5 -offset_left = -70.0 -offset_top = -70.0 -offset_right = -70.0 -offset_bottom = -70.0 grow_horizontal = 2 grow_vertical = 2 mouse_filter = 2 [node name="Panel" type="PanelContainer" parent="Background" unique_id=1782143434] -layout_mode = 0 -offset_right = 40.0 -offset_bottom = 40.0 +layout_mode = 1 +anchors_preset = 8 +anchor_left = 0.5 +anchor_top = 0.5 +anchor_right = 0.5 +anchor_bottom = 0.5 +offset_left = -150.0 +offset_top = -106.0 +offset_right = 150.0 +offset_bottom = 106.0 +grow_horizontal = 2 +grow_vertical = 2 [node name="VBoxContainer" type="VBoxContainer" parent="Background/Panel" unique_id=937959925] layout_mode = 2 @@ -34,9 +40,11 @@ theme_override_font_sizes/font_size = 8 horizontal_alignment = 1 vertical_alignment = 1 -[node name="Grid" type="GridContainer" parent="Background/Panel/VBoxContainer" unique_id=123587798] +[node name="WireCanvas" parent="Background/Panel/VBoxContainer" unique_id=1594830372 instance=ExtResource("2_sehdy")] +custom_minimum_size = Vector2(300, 180) layout_mode = 2 -columns = 4 +size_flags_horizontal = 4 +size_flags_vertical = 4 [node name="StatusLabel" type="Label" parent="Background/Panel/VBoxContainer" unique_id=1700512059] layout_mode = 2 diff --git a/ui/minigame/wire_canvas.gd b/ui/minigame/wire_canvas.gd new file mode 100644 index 0000000..5f05975 --- /dev/null +++ b/ui/minigame/wire_canvas.gd @@ -0,0 +1,12 @@ +extends Control + +func _ready() -> void: + mouse_filter = MOUSE_FILTER_STOP + +func _draw() -> void: + if owner is RepairMinigame: + owner.draw_wires(self) + +func _gui_input(event: InputEvent) -> void: + if owner is RepairMinigame: + owner.on_canvas_input(event) diff --git a/ui/minigame/wire_canvas.gd.uid b/ui/minigame/wire_canvas.gd.uid new file mode 100644 index 0000000..ac4a178 --- /dev/null +++ b/ui/minigame/wire_canvas.gd.uid @@ -0,0 +1 @@ +uid://dlb7sr4wrfc2h diff --git a/ui/minigame/wire_canvas.tscn b/ui/minigame/wire_canvas.tscn new file mode 100644 index 0000000..71f0051 --- /dev/null +++ b/ui/minigame/wire_canvas.tscn @@ -0,0 +1,8 @@ +[gd_scene format=3 uid="uid://dchwkw273wjq7"] + +[ext_resource type="Script" uid="uid://dlb7sr4wrfc2h" path="res://ui/minigame/wire_canvas.gd" id="1_pcg8e"] + +[node name="WireCanvas" type="Control" unique_id=1594830372] +layout_mode = 3 +anchors_preset = 0 +script = ExtResource("1_pcg8e")