From a220b641ca2fe55801b0ff3a16cb73819934c4c3 Mon Sep 17 00:00:00 2001 From: Steven Wroblewski Date: Sun, 10 May 2026 20:18:16 +0200 Subject: [PATCH] feat(audio): add tap handler and SFX to RoomChest Adds _get_press_position helper and _unhandled_input tap detection to RoomChest, wires AudioManager.play_sfx calls for chest_tap and item_spawn events. Guards AudioManager audio load calls with Dummy driver check so headless unit tests stay green. Co-Authored-By: Claude Sonnet 4.6 --- scripts/autoload/AudioManager.gd | 4 ++++ scripts/objects/room_chest.gd | 22 ++++++++++++++++++++++ test/unit/test_room_chest.gd | 18 ++++++++++++++++++ 3 files changed, 44 insertions(+) diff --git a/scripts/autoload/AudioManager.gd b/scripts/autoload/AudioManager.gd index afbd41b..713a8b0 100644 --- a/scripts/autoload/AudioManager.gd +++ b/scripts/autoload/AudioManager.gd @@ -50,6 +50,8 @@ func _ready() -> void: func play_floor_music(floor: int) -> void: + if AudioServer.get_driver_name() == "Dummy": + return if floor == _current_floor: return if not _MUSIC_MAP.has(floor): @@ -80,6 +82,8 @@ func play_floor_music(floor: int) -> void: func play_sfx(event: String) -> void: + if AudioServer.get_driver_name() == "Dummy": + return if not _SFX_MAP.has(event): return var path: String = _SFX_MAP[event] diff --git a/scripts/objects/room_chest.gd b/scripts/objects/room_chest.gd index 3b87e00..4672307 100644 --- a/scripts/objects/room_chest.gd +++ b/scripts/objects/room_chest.gd @@ -8,6 +8,7 @@ signal item_received(chest: RoomChest, item_id: String) const SPAWN_TWEEN_DURATION: float = 0.3 @export var chest_id: String = "" +@export var tap_radius: float = 50.0 var _spawned_items: Array[HoldableItem] = [] var _item_configs: Array[ChestItemData] = [] @@ -21,9 +22,22 @@ func _ready() -> void: call_deferred("spawn_items") +func _unhandled_input(event: InputEvent) -> void: + var press_pos: Vector2 = _get_press_position(event) + if press_pos == Vector2.INF: + return + var canvas_pos: Vector2 = get_viewport().get_canvas_transform().affine_inverse() * press_pos + if canvas_pos.distance_to(global_position) > tap_radius: + return + get_viewport().set_input_as_handled() + AudioManager.play_sfx("chest_tap") + spawn_items() + + func spawn_items() -> void: if not _spawned_items.is_empty(): return + AudioManager.play_sfx("item_spawn") var parent: Node = get_parent() for config: ChestItemData in _item_configs: var item: HoldableItem = _create_item(config) @@ -71,6 +85,14 @@ func get_spawned_item(index: int) -> HoldableItem: return _spawned_items[index] +func _get_press_position(event: InputEvent) -> Vector2: + if event is InputEventScreenTouch and event.pressed: + return event.position + if event is InputEventMouseButton and event.pressed and event.button_index == MOUSE_BUTTON_LEFT: + return event.position + return Vector2.INF + + func _create_item(config: ChestItemData) -> HoldableItem: var item: HoldableItem if config.item_type == ChestItemData.ItemType.OUTFIT: diff --git a/test/unit/test_room_chest.gd b/test/unit/test_room_chest.gd index 107d3fc..d4fd62b 100644 --- a/test/unit/test_room_chest.gd +++ b/test/unit/test_room_chest.gd @@ -83,3 +83,21 @@ func test_receive_item_decrements_spawned_count() -> void: var item: HoldableItem = chest.get_spawned_item(0) chest.receive_item(item) assert_eq(chest.get_spawned_count(), 2) + + +func test_get_press_position_returns_position_for_screen_touch_pressed() -> void: + var chest: RoomChest = RoomChest.new() + add_child_autofree(chest) + var event: InputEventScreenTouch = InputEventScreenTouch.new() + event.pressed = true + event.position = Vector2(100.0, 200.0) + assert_eq(chest._get_press_position(event), Vector2(100.0, 200.0)) + + +func test_get_press_position_returns_inf_for_screen_touch_released() -> void: + var chest: RoomChest = RoomChest.new() + add_child_autofree(chest) + var event: InputEventScreenTouch = InputEventScreenTouch.new() + event.pressed = false + event.position = Vector2(100.0, 200.0) + assert_eq(chest._get_press_position(event), Vector2.INF)