diff --git a/Scripts/AudioManager.gd b/Scripts/AudioManager.gd new file mode 100644 index 0000000..f06718b --- /dev/null +++ b/Scripts/AudioManager.gd @@ -0,0 +1,148 @@ +extends Node + +# Audio players for different sound effects +var click_start_player: AudioStreamPlayer +var click_end_player: AudioStreamPlayer +var construction_player: AudioStreamPlayer # Loops continuously! +var poof_player: AudioStreamPlayer +var level_clear_player: AudioStreamPlayer +var level_fail_player: AudioStreamPlayer + +# Sound enabled flag +var sound_enabled = true + +# Volume settings +var construction_normal_volume = -10 +var construction_ducked_volume = -20 +var is_construction_playing = false + +func _ready(): + # Create audio players + click_start_player = AudioStreamPlayer.new() + click_end_player = AudioStreamPlayer.new() + construction_player = AudioStreamPlayer.new() + poof_player = AudioStreamPlayer.new() + level_clear_player = AudioStreamPlayer.new() + level_fail_player = AudioStreamPlayer.new() + + # Add them as children + add_child(click_start_player) + add_child(click_end_player) + add_child(construction_player) + add_child(poof_player) + add_child(level_clear_player) + add_child(level_fail_player) + + # Load sound files + click_start_player.stream = load("res://SoundEffects/sfx_click_start.wav") + click_end_player.stream = load("res://SoundEffects/sfx_click_end.wav") + construction_player.stream = load("res://SoundEffects/sfx_construction.wav") + poof_player.stream = load("res://SoundEffects/sfx_poof.wav") + level_clear_player.stream = load("res://SoundEffects/sfx_level_clear.wav") + level_fail_player.stream = load("res://SoundEffects/sfx_level_fail.wav") + + # Set volume levels + click_start_player.volume_db = -5 + click_end_player.volume_db = -5 + construction_player.volume_db = construction_normal_volume + poof_player.volume_db = 0 + level_clear_player.volume_db = 5 + level_fail_player.volume_db = 5 + + print("AudioManager initialized successfully") + +# Start construction sound loop +func start_construction_loop(): + if sound_enabled and not is_construction_playing and construction_player.stream: + print("Starting construction loop...") + is_construction_playing = true + + # Connect to finished signal to loop manually + if not construction_player.finished.is_connected(_on_construction_finished): + construction_player.finished.connect(_on_construction_finished) + + construction_player.volume_db = construction_normal_volume + construction_player.play() + print("Construction sound should be playing now") + +# Manual loop replay when finished +func _on_construction_finished(): + if is_construction_playing: + construction_player.play() + +# Stop construction sound +func stop_construction_loop(): + if is_construction_playing: + print("Stopping construction loop...") + is_construction_playing = false + + # Fade out + var tween = create_tween() + tween.tween_property(construction_player, "volume_db", -80, 0.5) + await tween.finished + + construction_player.stop() + construction_player.volume_db = construction_normal_volume + +# Duck construction sound (make quieter) +func duck_construction(): + if is_construction_playing: + var tween = create_tween() + tween.tween_property(construction_player, "volume_db", construction_ducked_volume, 0.2) + +# Restore construction sound +func restore_construction(): + if is_construction_playing: + var tween = create_tween() + tween.tween_property(construction_player, "volume_db", construction_normal_volume, 0.3) + +# Play sound functions +func play_click_start(): + if sound_enabled and click_start_player.stream: + duck_construction() + click_start_player.play() + await get_tree().create_timer(0.3).timeout + restore_construction() + +func play_click_end(): + if sound_enabled and click_end_player.stream: + duck_construction() + click_end_player.play() + await get_tree().create_timer(0.3).timeout + restore_construction() + +func play_construction(): + print("play_construction() called") + start_construction_loop() + +func play_poof(): + if sound_enabled and poof_player.stream: + duck_construction() + poof_player.play() + await get_tree().create_timer(0.5).timeout + restore_construction() + +func play_level_clear(): + if sound_enabled and level_clear_player.stream: + stop_construction_loop() + level_clear_player.play() + +func play_level_fail(): + if sound_enabled and level_fail_player.stream: + stop_construction_loop() + level_fail_player.play() + +func toggle_sound(): + sound_enabled = !sound_enabled + if not sound_enabled: + stop_construction_loop() + print("Sound enabled: ", sound_enabled) + +func set_volume(db: float): + click_start_player.volume_db = db - 5 + click_end_player.volume_db = db - 5 + construction_normal_volume = db - 10 + construction_ducked_volume = db - 20 + poof_player.volume_db = db + level_clear_player.volume_db = db + 5 + level_fail_player.volume_db = db + 5 diff --git a/Scripts/ConveyerController.gd b/Scripts/ConveyerController.gd index abec8da..e7c6fc0 100644 --- a/Scripts/ConveyerController.gd +++ b/Scripts/ConveyerController.gd @@ -25,8 +25,9 @@ func setup(conveyer) -> void: self.conveyer.append(conveyer) self.can_send = false self.sendingEnd = false - self.started = false self.events = [] + self.started = false + # Called when the node enters the scene tree for the first time. func _ready() -> void: @@ -40,8 +41,10 @@ func _process(delta: float) -> void: pass func create_conveyor(): + conveyer[conveyerInd].set_point_position(0, selected.get_position()) conveyer[conveyerInd].set_point_position(1, destination[conveyerInd]) + AudioManager.play_construction() conveyerInd+=1 func send_event(): diff --git a/Scripts/SinkClick.gd b/Scripts/SinkClick.gd index 6e5204a..35de978 100644 --- a/Scripts/SinkClick.gd +++ b/Scripts/SinkClick.gd @@ -6,6 +6,7 @@ func _input_event(viewport, event, shape_idx): func on_click(): print("hey") + AudioManager.play_click_end() ConveyerController.destination.append(get_parent().get_position()) transfer_box() diff --git a/Scripts/draggable_filter.gd b/Scripts/draggable_filter.gd index baa994c..5e6ce1f 100644 --- a/Scripts/draggable_filter.gd +++ b/Scripts/draggable_filter.gd @@ -38,4 +38,5 @@ func _on_area_entered(area: Area2D) -> void: if area.is_in_group("Box"): if area.get_parent().boxType != filterColor and area.get_parent().sending == true: print("kill it") + AudioManager.play_poof() area.get_parent().queue_free() diff --git a/Scripts/event_box.gd b/Scripts/event_box.gd index 30d1d50..b83bd02 100644 --- a/Scripts/event_box.gd +++ b/Scripts/event_box.gd @@ -44,14 +44,4 @@ func _input_event(viewport, event, shape_idx) -> void: func on_click(): print("hi") ConveyerController.selected = self - - -func _on_area_2d_mouse_entered(): - $hoverlabel.visible = true; - - - - - -func _on_area_2d_mouse_exited(): - $hoverlabel.visible = false# Replace with function body. + AudioManager.play_click_start() diff --git a/Scripts/level.gd b/Scripts/level.gd index 19b15b6..5565b4c 100644 --- a/Scripts/level.gd +++ b/Scripts/level.gd @@ -33,19 +33,22 @@ func next_level(): message_display.z_index = 999 if nextLevel: print("success") + AudioManager.play_level_clear() message_display.show_message("Success") await message_display.show_message_for_duration(2.0) message_display.visible = false levelind+=1 if levelind!=levels.size(): + # CRITICAL FIXInitialize BEFORE changing scene, not after! + ConveyerController.initialise() var next_level_path="res://Scenes/"+levels[levelind]+".tscn" get_tree().change_scene_to_file(next_level_path) - ConveyerController.initialise() else: print("End of Levels.") get_tree().change_scene_to_file("res://Scenes/end_of_all_levels.tscn") else: print("Failed. Try Again") + AudioManager.play_level_fail() message_display.show_message("Failed. Try Again") await message_display.show_message_for_duration(2.0) message_display.visible = false diff --git a/project.godot b/project.godot index d473b09..fdbdc1c 100644 --- a/project.godot +++ b/project.godot @@ -19,6 +19,7 @@ config/icon="res://icon.svg" ConveyerController="*res://Scripts/ConveyerController.gd" Level="*res://Scripts/level.gd" +AudioManager="*res://Scripts/AudioManager.gd" [input]