From 8c1e6a1ffc25f2c788d364e9ebc8f059b42a766d Mon Sep 17 00:00:00 2001 From: Tiger Jove Date: Fri, 16 Jan 2026 22:05:21 +0100 Subject: [PATCH] fix: cards now much more clickable and properly separate themselves --- src/logic-scenes/board/card collider.gd | 4 -- src/logic-scenes/board/card collider.gd.uid | 1 - src/logic-scenes/board/card-board.gd | 46 +++++++++++++-- src/logic-scenes/board/card.gd | 17 ++++-- src/logic-scenes/board/physics-board.tscn | 63 +-------------------- src/logic-scenes/board/sticky-note.gd | 14 +++-- 6 files changed, 61 insertions(+), 84 deletions(-) delete mode 100644 src/logic-scenes/board/card collider.gd delete mode 100644 src/logic-scenes/board/card collider.gd.uid diff --git a/src/logic-scenes/board/card collider.gd b/src/logic-scenes/board/card collider.gd deleted file mode 100644 index b95c476..0000000 --- a/src/logic-scenes/board/card collider.gd +++ /dev/null @@ -1,4 +0,0 @@ -class_name CardCollider -extends Draggable - -@export var direction: Vector2 = Vector2.ZERO diff --git a/src/logic-scenes/board/card collider.gd.uid b/src/logic-scenes/board/card collider.gd.uid deleted file mode 100644 index d0acfec..0000000 --- a/src/logic-scenes/board/card collider.gd.uid +++ /dev/null @@ -1 +0,0 @@ -uid://ddy8kb2hjvgss diff --git a/src/logic-scenes/board/card-board.gd b/src/logic-scenes/board/card-board.gd index 6974483..14fd94c 100644 --- a/src/logic-scenes/board/card-board.gd +++ b/src/logic-scenes/board/card-board.gd @@ -179,7 +179,43 @@ func populate_board(card_names: Array[StringName]): currently_active_node = dropzone.get_child(0) ## Generates a random position within the dropzone bounds -func _generate_random_position() -> Vector2: +## Attempts to avoid overlapping with existing cards/stickies +func _generate_random_position(min_distance: float = 150.0) -> Vector2: + var max_attempts := 20 + var attempt := 0 + var card_diameter := 336.0 # Card diameter from card.gd + var sticky_diameter := 312.0 # Sticky diameter from sticky-note.gd + + while attempt < max_attempts: + var pos := Vector2( + randi_range(dropzone_padding, int(dropzone_size.x)), + randi_range(dropzone_padding, int(dropzone_size.y)) + ) + + # Check if this position is far enough from existing items + var is_valid := true + for child in dropzone.get_children(): + if child is Card or child is StickyNote: + var distance := pos.distance_to(child.position) + var required_distance := min_distance + + # Use actual diameters for more precise collision checking + if child is Card: + required_distance = card_diameter * 0.6 # 60% of diameter for some overlap tolerance + elif child is StickyNote: + required_distance = sticky_diameter * 0.6 + + if distance < required_distance: + is_valid = false + break + + if is_valid: + return pos + + attempt += 1 + + # If we couldn't find a good position after max attempts, return a random one + # This prevents infinite loops when the board is crowded return Vector2( randi_range(dropzone_padding, int(dropzone_size.x)), randi_range(dropzone_padding, int(dropzone_size.y)) @@ -274,8 +310,8 @@ func _handle_sticky_exchange(new_sticky: StickyNote, card: Card) -> void: return # Reset visual state for old sticky - old_sticky.rotation = old_sticky.base_rotation - old_sticky.scale = old_sticky.base_scale + old_sticky.rotation = 0.0 + old_sticky.scale = Vector2.ONE old_sticky.z_index = 0 # Exchanged sticky always goes to sticky_note_container @@ -456,8 +492,8 @@ func handle_drop(draggable: Draggable) -> int: sticky.on_board = true sticky.is_dragable = true # Reset visual state - sticky.rotation = sticky.base_rotation - sticky.scale = sticky.base_scale + sticky.rotation = 0.0 + sticky.scale = Vector2.ONE elif draggable is Card: # Handle card drop insert_area(dropzone, draggable) diff --git a/src/logic-scenes/board/card.gd b/src/logic-scenes/board/card.gd index 0eb49c9..d63fbec 100644 --- a/src/logic-scenes/board/card.gd +++ b/src/logic-scenes/board/card.gd @@ -1,4 +1,4 @@ -extends CardCollider +extends Draggable class_name Card var card_id @@ -193,10 +193,8 @@ func _process(delta: float) -> void: if get_overlapping_areas().size() > 0 and is_dragable: for area in get_overlapping_areas(): - if area is Card or area is CardCollider: - if area is CardCollider: - position += area.direction * delta - elif not (area.highlighted or self.highlighted) and area.is_dragable: + if area is Card: + if not (area.highlighted or self.highlighted) and area.is_dragable: var diff:Vector2 = position - area.position position -= diff.normalized() * ((diff.length()-diameter)/diameter) * bounce_speed * (delta/(1.0/60)) @@ -248,9 +246,16 @@ func get_attached_sticky_note() -> StickyNote: func preview_sticky_note(sticky_note: StickyNote): + if not is_instance_valid(sticky_note): + return sticky_note.reparent(self.get_parent()) sticky_note.attached_to = self - sticky_note.tween_transform_to(Transform2D(0, global_position + sticky_note_position + 0 * Vector2(sticky_note.diameter, sticky_note.diameter))) + # Use a safe transform with validated position + var target_pos := global_position + sticky_note_position + if is_finite(target_pos.x) and is_finite(target_pos.y): + sticky_note.tween_transform_to(Transform2D(0, target_pos)) + else: + push_warning("Card.preview_sticky_note: Invalid position calculated, skipping tween") func attach_sticky_note(sticky_note: StickyNote) -> bool: if has_sticky_note_attached(): diff --git a/src/logic-scenes/board/physics-board.tscn b/src/logic-scenes/board/physics-board.tscn index 77901a2..7095990 100644 --- a/src/logic-scenes/board/physics-board.tscn +++ b/src/logic-scenes/board/physics-board.tscn @@ -1,4 +1,4 @@ -[gd_scene load_steps=24 format=3 uid="uid://bnskiyx1sksww"] +[gd_scene load_steps=21 format=3 uid="uid://bnskiyx1sksww"] [ext_resource type="Texture2D" uid="uid://bi3xqdknw5tpe" path="res://logic-scenes/board/board-texture/Cork002_2K_Color.png" id="1_8brxc"] [ext_resource type="Shader" uid="uid://kyd37e0s6fdu" path="res://logic-scenes/board/physics-board.gdshader" id="1_ggnth"] @@ -6,7 +6,6 @@ [ext_resource type="AudioStream" uid="uid://bywmf3patoe56" path="res://base-environments/youth_room/audio/board_completed.wav" id="5_qjqy3"] [ext_resource type="AudioStream" uid="uid://bgtohhyd8whbm" path="res://base-environments/youth_room/audio/board_completed_de.wav" id="6_ni75f"] [ext_resource type="AudioStream" uid="uid://dj8fpajqhj4k7" path="res://base-environments/youth_room/audio/board_incomplete.wav" id="6_vtvtf"] -[ext_resource type="Script" uid="uid://ddy8kb2hjvgss" path="res://logic-scenes/board/card collider.gd" id="6_wpxls"] [ext_resource type="AudioStream" uid="uid://brolrc3lhaeid" path="res://base-environments/youth_room/audio/board_unfitting.wav" id="7_0phgc"] [ext_resource type="AudioStream" uid="uid://swlo6elqs4vx" path="res://base-environments/youth_room/audio/board_incomplete_de.wav" id="7_2qppy"] [ext_resource type="Script" uid="uid://c1oub0cs7cph6" path="res://dev-util/stereo-switch.gd" id="8_ni75f"] @@ -19,12 +18,6 @@ shader_parameter/magic_scale_factor = 1500.0 [sub_resource type="StyleBoxFlat" id="StyleBoxFlat_m1g7s"] -[sub_resource type="RectangleShape2D" id="RectangleShape2D_5ri3m"] -size = Vector2(4262, 766.5) - -[sub_resource type="RectangleShape2D" id="RectangleShape2D_ivo5o"] -size = Vector2(4249, 766.5) - [sub_resource type="Animation" id="Animation_qjqy3"] length = 0.001 @@ -184,60 +177,6 @@ horizontal_scroll_mode = 0 [node name="VBoxContainer" type="VBoxContainer" parent="HBoxContainer/ScrollContainer"] layout_mode = 2 -[node name="up" type="Control" parent="."] -layout_mode = 2 -size_flags_horizontal = 4 -size_flags_vertical = 0 - -[node name="border_up" type="Area2D" parent="up"] -script = ExtResource("6_wpxls") -direction = Vector2(0, 100) - -[node name="CollisionShape2D" type="CollisionShape2D" parent="up/border_up"] -position = Vector2(-58, -369) -shape = SubResource("RectangleShape2D_5ri3m") - -[node name="left" type="Control" parent="."] -layout_mode = 2 -size_flags_horizontal = 0 -size_flags_vertical = 4 - -[node name="border_left" type="Area2D" parent="left"] -script = ExtResource("6_wpxls") -direction = Vector2(100, 0) - -[node name="CollisionShape2D" type="CollisionShape2D" parent="left/border_left"] -position = Vector2(-371, -21.5) -rotation = 1.5708 -shape = SubResource("RectangleShape2D_ivo5o") - -[node name="down" type="Control" parent="."] -layout_mode = 2 -size_flags_horizontal = 4 -size_flags_vertical = 8 - -[node name="border_down" type="Area2D" parent="down"] -script = ExtResource("6_wpxls") -direction = Vector2(0, -100) - -[node name="CollisionShape2D" type="CollisionShape2D" parent="down/border_down"] -position = Vector2(2, 377) -shape = SubResource("RectangleShape2D_5ri3m") - -[node name="right" type="Control" parent="."] -layout_mode = 2 -size_flags_horizontal = 8 -size_flags_vertical = 4 - -[node name="border_left" type="Area2D" parent="right"] -script = ExtResource("6_wpxls") -direction = Vector2(-100, 0) - -[node name="CollisionShape2D" type="CollisionShape2D" parent="right/border_left"] -position = Vector2(20, 13) -rotation = 1.5708 -shape = SubResource("RectangleShape2D_ivo5o") - [node name="instructions_panel" type="PanelContainer" parent="."] layout_mode = 2 size_flags_horizontal = 4 diff --git a/src/logic-scenes/board/sticky-note.gd b/src/logic-scenes/board/sticky-note.gd index 00aa782..3aeca12 100644 --- a/src/logic-scenes/board/sticky-note.gd +++ b/src/logic-scenes/board/sticky-note.gd @@ -57,8 +57,6 @@ var label: Label @export var voice_line: AudioStream = null @export var is_dragable: bool = false -@onready var base_rotation := rotation -@onready var base_scale := scale var mouse_offset: Vector2 @@ -95,10 +93,8 @@ func _on_text_updated(): func _process(delta: float) -> void: if get_overlapping_areas().size() > 0 and is_dragable and on_board: for area in get_overlapping_areas(): - if area is Card or area is CardCollider: - if area is CardCollider: - position += area.direction * delta - elif not area.highlighted or self.highlighted: + if area is Card: + if not area.highlighted or self.highlighted: var diff:Vector2 = position - area.position position -= diff.normalized() * ((diff.length()-diameter)/diameter) * bounce_speed * (delta/(1.0/60)) @@ -145,6 +141,12 @@ func is_sticky_note_in_panel() -> bool: var transform_tween: Tween func tween_transform_to(target: Transform2D): + # Validate position to prevent teleporting + if not is_finite(target.origin.x) or not is_finite(target.origin.y): + push_warning("StickyNote.tween_transform_to: Invalid position, skipping tween") + transform_tween_finished.emit() + return + if transform_tween and transform_tween.is_running(): transform_tween.stop()