fix: cards now much more clickable and properly separate themselves
This commit is contained in:
parent
f8743b18b5
commit
8c1e6a1ffc
|
|
@ -1,4 +0,0 @@
|
||||||
class_name CardCollider
|
|
||||||
extends Draggable
|
|
||||||
|
|
||||||
@export var direction: Vector2 = Vector2.ZERO
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
uid://ddy8kb2hjvgss
|
|
||||||
|
|
@ -179,7 +179,43 @@ func populate_board(card_names: Array[StringName]):
|
||||||
currently_active_node = dropzone.get_child(0)
|
currently_active_node = dropzone.get_child(0)
|
||||||
|
|
||||||
## Generates a random position within the dropzone bounds
|
## 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(
|
return Vector2(
|
||||||
randi_range(dropzone_padding, int(dropzone_size.x)),
|
randi_range(dropzone_padding, int(dropzone_size.x)),
|
||||||
randi_range(dropzone_padding, int(dropzone_size.y))
|
randi_range(dropzone_padding, int(dropzone_size.y))
|
||||||
|
|
@ -274,8 +310,8 @@ func _handle_sticky_exchange(new_sticky: StickyNote, card: Card) -> void:
|
||||||
return
|
return
|
||||||
|
|
||||||
# Reset visual state for old sticky
|
# Reset visual state for old sticky
|
||||||
old_sticky.rotation = old_sticky.base_rotation
|
old_sticky.rotation = 0.0
|
||||||
old_sticky.scale = old_sticky.base_scale
|
old_sticky.scale = Vector2.ONE
|
||||||
old_sticky.z_index = 0
|
old_sticky.z_index = 0
|
||||||
|
|
||||||
# Exchanged sticky always goes to sticky_note_container
|
# Exchanged sticky always goes to sticky_note_container
|
||||||
|
|
@ -456,8 +492,8 @@ func handle_drop(draggable: Draggable) -> int:
|
||||||
sticky.on_board = true
|
sticky.on_board = true
|
||||||
sticky.is_dragable = true
|
sticky.is_dragable = true
|
||||||
# Reset visual state
|
# Reset visual state
|
||||||
sticky.rotation = sticky.base_rotation
|
sticky.rotation = 0.0
|
||||||
sticky.scale = sticky.base_scale
|
sticky.scale = Vector2.ONE
|
||||||
elif draggable is Card:
|
elif draggable is Card:
|
||||||
# Handle card drop
|
# Handle card drop
|
||||||
insert_area(dropzone, draggable)
|
insert_area(dropzone, draggable)
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
extends CardCollider
|
extends Draggable
|
||||||
class_name Card
|
class_name Card
|
||||||
|
|
||||||
var card_id
|
var card_id
|
||||||
|
|
@ -193,10 +193,8 @@ func _process(delta: float) -> void:
|
||||||
|
|
||||||
if get_overlapping_areas().size() > 0 and is_dragable:
|
if get_overlapping_areas().size() > 0 and is_dragable:
|
||||||
for area in get_overlapping_areas():
|
for area in get_overlapping_areas():
|
||||||
if area is Card or area is CardCollider:
|
if area is Card:
|
||||||
if area is CardCollider:
|
if not (area.highlighted or self.highlighted) and area.is_dragable:
|
||||||
position += area.direction * delta
|
|
||||||
elif not (area.highlighted or self.highlighted) and area.is_dragable:
|
|
||||||
var diff:Vector2 = position - area.position
|
var diff:Vector2 = position - area.position
|
||||||
position -= diff.normalized() * ((diff.length()-diameter)/diameter) * bounce_speed * (delta/(1.0/60))
|
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):
|
func preview_sticky_note(sticky_note: StickyNote):
|
||||||
|
if not is_instance_valid(sticky_note):
|
||||||
|
return
|
||||||
sticky_note.reparent(self.get_parent())
|
sticky_note.reparent(self.get_parent())
|
||||||
sticky_note.attached_to = self
|
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:
|
func attach_sticky_note(sticky_note: StickyNote) -> bool:
|
||||||
if has_sticky_note_attached():
|
if has_sticky_note_attached():
|
||||||
|
|
|
||||||
|
|
@ -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="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"]
|
[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://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://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="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://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="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"]
|
[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="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"]
|
[sub_resource type="Animation" id="Animation_qjqy3"]
|
||||||
length = 0.001
|
length = 0.001
|
||||||
|
|
||||||
|
|
@ -184,60 +177,6 @@ horizontal_scroll_mode = 0
|
||||||
[node name="VBoxContainer" type="VBoxContainer" parent="HBoxContainer/ScrollContainer"]
|
[node name="VBoxContainer" type="VBoxContainer" parent="HBoxContainer/ScrollContainer"]
|
||||||
layout_mode = 2
|
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="."]
|
[node name="instructions_panel" type="PanelContainer" parent="."]
|
||||||
layout_mode = 2
|
layout_mode = 2
|
||||||
size_flags_horizontal = 4
|
size_flags_horizontal = 4
|
||||||
|
|
|
||||||
|
|
@ -57,8 +57,6 @@ var label: Label
|
||||||
|
|
||||||
@export var voice_line: AudioStream = null
|
@export var voice_line: AudioStream = null
|
||||||
@export var is_dragable: bool = false
|
@export var is_dragable: bool = false
|
||||||
@onready var base_rotation := rotation
|
|
||||||
@onready var base_scale := scale
|
|
||||||
|
|
||||||
var mouse_offset: Vector2
|
var mouse_offset: Vector2
|
||||||
|
|
||||||
|
|
@ -95,10 +93,8 @@ func _on_text_updated():
|
||||||
func _process(delta: float) -> void:
|
func _process(delta: float) -> void:
|
||||||
if get_overlapping_areas().size() > 0 and is_dragable and on_board:
|
if get_overlapping_areas().size() > 0 and is_dragable and on_board:
|
||||||
for area in get_overlapping_areas():
|
for area in get_overlapping_areas():
|
||||||
if area is Card or area is CardCollider:
|
if area is Card:
|
||||||
if area is CardCollider:
|
if not area.highlighted or self.highlighted:
|
||||||
position += area.direction * delta
|
|
||||||
elif not area.highlighted or self.highlighted:
|
|
||||||
var diff:Vector2 = position - area.position
|
var diff:Vector2 = position - area.position
|
||||||
position -= diff.normalized() * ((diff.length()-diameter)/diameter) * bounce_speed * (delta/(1.0/60))
|
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
|
var transform_tween: Tween
|
||||||
|
|
||||||
func tween_transform_to(target: Transform2D):
|
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():
|
if transform_tween and transform_tween.is_running():
|
||||||
transform_tween.stop()
|
transform_tween.stop()
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue