Implement BGM and SFX event system

This commit is contained in:
2024-09-14 16:01:55 -07:00
parent 0a71339bbe
commit cd8806a9fe
38 changed files with 718 additions and 116 deletions

View File

@@ -10,12 +10,121 @@ public partial class InGameAudio : Node
{
public override void _Notification(int what) => this.Notify(what);
[Dependency] public IAppRepo AppRepo => this.DependOn<IAppRepo>();
[Dependency] public IGameRepo GameRepo => this.DependOn<IGameRepo>();
[Dependency] public IGameEventDepot GameEventDepot => this.DependOn<IGameEventDepot>();
#region BGM Nodes
[Node] public IDimmableAudioStreamPlayer MenuBGM { get; set; } = default!;
[Node] public IDimmableAudioStreamPlayer OverworldBGM { get; set; } = default!;
[Node] public IDimmableAudioStreamPlayer MenuBgm { get; set; } = default!;
[Node] public IDimmableAudioStreamPlayer OverworldBgm { get; set; } = default!;
[Node] public IDimmableAudioStreamPlayer DungeonThemeABgm { get; set; } = default!;
[Node] public IDimmableAudioStreamPlayer DungeonThemeBBgm { get; set; } = default!;
[Node] public IDimmableAudioStreamPlayer DungeonThemeCBgm { get; set; } = default!;
#endregion
#region SFX Nodes
[Node] public IAudioStreamPlayer PlayerAttackSFX { get; set; } = default!;
[Node] public IAudioStreamPlayer MenuScrollSFX { get; set; } = default!;
[Node] public IAudioStreamPlayer EquipSFX { get; set; } = default!;
[Node] public IAudioStreamPlayer MenuBackSFX { get; set; } = default!;
[Node] public IAudioStreamPlayer InventorySortedSFX { get; set; } = default!;
[Node] public IAudioStreamPlayer HealingItemSFX { get; set; } = default!;
[Node] public IAudioStreamPlayer TeleportSFX { get; set; } = default!;
#endregion
public IInGameAudioLogic InGameAudioLogic { get; set; } = default!;
public InGameAudioLogic.IBinding InGameAudioBinding { get; set; } = default!;
public void Setup()
{
InGameAudioLogic = new InGameAudioLogic();
}
public void OnResolved()
{
InGameAudioLogic.Set(AppRepo);
InGameAudioLogic.Set(GameRepo);
InGameAudioLogic.Set(GameEventDepot);
InGameAudioBinding = InGameAudioLogic.Bind();
InGameAudioBinding
.Handle((in InGameAudioLogic.Output.PlayOverworldMusic _) => StartOverworldMusic())
.Handle((in InGameAudioLogic.Output.PlayDungeonThemeAMusic _) => StartDungeonThemeA())
.Handle((in InGameAudioLogic.Output.PlayMenuScrollSound _) => PlayMenuScrollSound())
.Handle((in InGameAudioLogic.Output.PlayEquipSound _) => PlayEquipSound())
.Handle((in InGameAudioLogic.Output.PlayMenuBackSound _) => PlayMenuBackSound())
.Handle((in InGameAudioLogic.Output.PlayInventorySortedSound _) => PlayInventorySortedSound())
.Handle((in InGameAudioLogic.Output.PlayHealingItemSound _) => PlayHealingItemSound())
.Handle((in InGameAudioLogic.Output.PlayTeleportSound _) => PlayTeleportSound());
InGameAudioLogic.Start();
}
public void OnExitTree()
{
InGameAudioLogic.Stop();
InGameAudioBinding.Dispose();
}
private void StartOverworldMusic()
{
OverworldBgm.Stop();
OverworldBgm.FadeIn();
}
private void StartDungeonThemeA()
{
OverworldBgm.FadeOut();
DungeonThemeABgm.Stop();
DungeonThemeABgm.FadeIn();
}
private void PlayMenuScrollSound()
{
MenuScrollSFX.Stop();
MenuScrollSFX.Play();
}
private void PlayEquipSound()
{
EquipSFX.Stop();
EquipSFX.Play();
}
private void PlayMenuBackSound()
{
MenuBackSFX.Stop();
MenuBackSFX.Play();
}
private void PlayInventorySortedSound()
{
InventorySortedSFX.Stop();
InventorySortedSFX.Play();
}
private void PlayHealingItemSound()
{
HealingItemSFX.Stop();
HealingItemSFX.Play();
}
private void PlayTeleportSound()
{
TeleportSFX.Stop();
TeleportSFX.Play();
}
}

View File

@@ -1,19 +1,93 @@
[gd_scene load_steps=3 format=3 uid="uid://b16ejcwanod72"]
[gd_scene load_steps=13 format=3 uid="uid://b16ejcwanod72"]
[ext_resource type="Script" path="res://src/audio/InGameAudio.cs" id="1_gpmcr"]
[ext_resource type="AudioStream" uid="uid://dfu0fksb6slhx" path="res://src/audio/music/droney.mp3" id="2_8hfyr"]
[ext_resource type="Script" path="res://src/audio/DimmableAudioStreamPlayer.cs" id="2_857rw"]
[ext_resource type="AudioStream" uid="uid://d2jrktp06xsba" path="res://src/audio/music/crossing-the-gate.mp3" id="3_wbmd6"]
[ext_resource type="AudioStream" uid="uid://dn2e2hqujlia1" path="res://src/audio/music/tar-winds.mp3" id="4_surnl"]
[ext_resource type="AudioStream" uid="uid://t3g04u722f2k" path="res://src/audio/music/useless immune system-1.mp3" id="6_agr3r"]
[ext_resource type="AudioStream" uid="uid://dor0in0x2fg48" path="res://src/audio/sfx/TempFFVII/menu-move.ogg" id="7_777nl"]
[ext_resource type="AudioStream" uid="uid://r1tryiit38i8" path="res://src/audio/sfx/TempFFVII/menu-back.ogg" id="8_1xcgo"]
[ext_resource type="AudioStream" uid="uid://bjj61s8q2gwb8" path="res://src/audio/sfx/TempFFVII/junction.ogg" id="8_kwybb"]
[ext_resource type="AudioStream" uid="uid://myx4s8lmarc2" path="res://src/audio/sfx/TempFFVII/something-earned.ogg" id="10_3lcw5"]
[ext_resource type="AudioStream" uid="uid://dci08kmwsu6k1" path="res://src/audio/sfx/TempFFVII/teleport.ogg" id="11_offhc"]
[ext_resource type="AudioStream" uid="uid://d3sn7c614uj2n" path="res://src/audio/sfx/TempFFVII/sort.ogg" id="12_wprjr"]
[node name="InGameAudio" type="Node"]
process_mode = 3
script = ExtResource("1_gpmcr")
[node name="MenuBGM" type="AudioStreamPlayer" parent="."]
[node name="MenuBgm" type="AudioStreamPlayer" parent="."]
unique_name_in_owner = true
stream = ExtResource("2_8hfyr")
parameters/looping = true
script = ExtResource("2_857rw")
[node name="OverworldBGM" type="AudioStreamPlayer" parent="."]
[node name="OverworldBgm" type="AudioStreamPlayer" parent="."]
unique_name_in_owner = true
stream = ExtResource("3_wbmd6")
volume_db = -15.0
parameters/looping = true
script = ExtResource("2_857rw")
[node name="DungeonThemeABgm" type="AudioStreamPlayer" parent="."]
unique_name_in_owner = true
stream = ExtResource("4_surnl")
volume_db = -15.0
parameters/looping = true
script = ExtResource("2_857rw")
[node name="DungeonThemeBBgm" type="AudioStreamPlayer" parent="."]
unique_name_in_owner = true
stream = ExtResource("6_agr3r")
volume_db = -15.0
parameters/looping = true
script = ExtResource("2_857rw")
[node name="DungeonThemeCBgm" type="AudioStreamPlayer" parent="."]
unique_name_in_owner = true
volume_db = -15.0
script = ExtResource("2_857rw")
[node name="Title_Bgm" type="AudioStreamPlayer" parent="."]
unique_name_in_owner = true
volume_db = -15.0
script = ExtResource("2_857rw")
[node name="PlayerAttackSFX" type="AudioStreamPlayer" parent="."]
unique_name_in_owner = true
[node name="MenuScrollSFX" type="AudioStreamPlayer" parent="."]
unique_name_in_owner = true
stream = ExtResource("7_777nl")
volume_db = -10.0
[node name="MenuBackSFX" type="AudioStreamPlayer" parent="."]
unique_name_in_owner = true
stream = ExtResource("8_1xcgo")
volume_db = -10.0
[node name="EquipSFX" type="AudioStreamPlayer" parent="."]
unique_name_in_owner = true
stream = ExtResource("8_kwybb")
volume_db = -10.0
[node name="HealSFX" type="AudioStreamPlayer" parent="."]
unique_name_in_owner = true
stream = ExtResource("10_3lcw5")
volume_db = -10.0
[node name="TeleportSFX" type="AudioStreamPlayer" parent="."]
unique_name_in_owner = true
stream = ExtResource("11_offhc")
volume_db = -18.0
[node name="InventorySortedSFX" type="AudioStreamPlayer" parent="."]
unique_name_in_owner = true
stream = ExtResource("12_wprjr")
volume_db = -15.0
[node name="HealingItemSFX" type="AudioStreamPlayer" parent="."]
unique_name_in_owner = true
stream = ExtResource("10_3lcw5")
volume_db = -15.0

Binary file not shown.

View File

@@ -0,0 +1,19 @@
[remap]
importer="mp3"
type="AudioStreamMP3"
uid="uid://t3g04u722f2k"
path="res://.godot/imported/useless immune system-1.mp3-e40a7d02f05bda566c0eac2b33f080a0.mp3str"
[deps]
source_file="res://src/audio/music/useless immune system-1.mp3"
dest_files=["res://.godot/imported/useless immune system-1.mp3-e40a7d02f05bda566c0eac2b33f080a0.mp3str"]
[params]
loop=false
loop_offset=0
bpm=0
beat_count=0
bar_beats=4

View File

@@ -0,0 +1,23 @@
[remap]
importer="wav"
type="AudioStreamWAV"
uid="uid://t28qhjuibv3f"
valid=false
[deps]
source_file="res://src/audio/sfx/TempFFVII/Equip.wav"
[params]
force/8_bit=false
force/mono=false
force/max_rate=false
force/max_rate_hz=44100
edit/trim=false
edit/normalize=false
edit/loop_mode=0
edit/loop_begin=0
edit/loop_end=-1
compress/mode=0

Binary file not shown.

View File

@@ -0,0 +1,19 @@
[remap]
importer="oggvorbisstr"
type="AudioStreamOggVorbis"
uid="uid://bjj61s8q2gwb8"
path="res://.godot/imported/junction.ogg-f4350086a08e048d3008edcdc25abf96.oggvorbisstr"
[deps]
source_file="res://src/audio/sfx/TempFFVII/junction.ogg"
dest_files=["res://.godot/imported/junction.ogg-f4350086a08e048d3008edcdc25abf96.oggvorbisstr"]
[params]
loop=false
loop_offset=0
bpm=0
beat_count=0
bar_beats=4

Binary file not shown.

View File

@@ -0,0 +1,19 @@
[remap]
importer="oggvorbisstr"
type="AudioStreamOggVorbis"
uid="uid://r1tryiit38i8"
path="res://.godot/imported/menu-back.ogg-3ec385c1a9cfaaa1be4ba85197708f0c.oggvorbisstr"
[deps]
source_file="res://src/audio/sfx/TempFFVII/menu-back.ogg"
dest_files=["res://.godot/imported/menu-back.ogg-3ec385c1a9cfaaa1be4ba85197708f0c.oggvorbisstr"]
[params]
loop=false
loop_offset=0
bpm=0
beat_count=0
bar_beats=4

Binary file not shown.

View File

@@ -0,0 +1,19 @@
[remap]
importer="oggvorbisstr"
type="AudioStreamOggVorbis"
uid="uid://dor0in0x2fg48"
path="res://.godot/imported/menu-move.ogg-d71b0989e00dd1d4488a72c7dde3d41d.oggvorbisstr"
[deps]
source_file="res://src/audio/sfx/TempFFVII/menu-move.ogg"
dest_files=["res://.godot/imported/menu-move.ogg-d71b0989e00dd1d4488a72c7dde3d41d.oggvorbisstr"]
[params]
loop=false
loop_offset=0
bpm=0
beat_count=0
bar_beats=4

Binary file not shown.

View File

@@ -0,0 +1,24 @@
[remap]
importer="wav"
type="AudioStreamWAV"
uid="uid://tce7m18vkgao"
path="res://.godot/imported/menu.wav-3931712b8a8483f269018c4a880368b2.sample"
[deps]
source_file="res://src/audio/sfx/TempFFVII/menu.wav"
dest_files=["res://.godot/imported/menu.wav-3931712b8a8483f269018c4a880368b2.sample"]
[params]
force/8_bit=false
force/mono=false
force/max_rate=false
force/max_rate_hz=44100
edit/trim=false
edit/normalize=false
edit/loop_mode=0
edit/loop_begin=0
edit/loop_end=-1
compress/mode=0

Binary file not shown.

View File

@@ -0,0 +1,19 @@
[remap]
importer="oggvorbisstr"
type="AudioStreamOggVorbis"
uid="uid://myx4s8lmarc2"
path="res://.godot/imported/something-earned.ogg-150627e4deb45db30e8dd2f98ddcc5a8.oggvorbisstr"
[deps]
source_file="res://src/audio/sfx/TempFFVII/something-earned.ogg"
dest_files=["res://.godot/imported/something-earned.ogg-150627e4deb45db30e8dd2f98ddcc5a8.oggvorbisstr"]
[params]
loop=false
loop_offset=0
bpm=0
beat_count=0
bar_beats=4

Binary file not shown.

View File

@@ -0,0 +1,19 @@
[remap]
importer="oggvorbisstr"
type="AudioStreamOggVorbis"
uid="uid://d3sn7c614uj2n"
path="res://.godot/imported/sort.ogg-cb2a2c4769c8e6574221a3c313e75bcf.oggvorbisstr"
[deps]
source_file="res://src/audio/sfx/TempFFVII/sort.ogg"
dest_files=["res://.godot/imported/sort.ogg-cb2a2c4769c8e6574221a3c313e75bcf.oggvorbisstr"]
[params]
loop=false
loop_offset=0
bpm=0
beat_count=0
bar_beats=4

Binary file not shown.

View File

@@ -0,0 +1,19 @@
[remap]
importer="oggvorbisstr"
type="AudioStreamOggVorbis"
uid="uid://dci08kmwsu6k1"
path="res://.godot/imported/teleport.ogg-9024f7b675b201a391dee183da020b1d.oggvorbisstr"
[deps]
source_file="res://src/audio/sfx/TempFFVII/teleport.ogg"
dest_files=["res://.godot/imported/teleport.ogg-9024f7b675b201a391dee183da020b1d.oggvorbisstr"]
[params]
loop=false
loop_offset=0
bpm=0
beat_count=0
bar_beats=4

View File

@@ -0,0 +1,34 @@
namespace GameJamDungeon
{
public partial class InGameAudioLogic
{
public static class Output
{
#region BGM
public readonly record struct PlayOverworldMusic;
public readonly record struct PlayDungeonThemeAMusic;
#endregion
#region SFX
public readonly record struct PlayPlayerAttackSound;
public readonly record struct PlayMenuScrollSound;
public readonly record struct PlayEquipSound;
public readonly record struct PlayInventorySortedSound;
public readonly record struct PlayMenuBackSound;
public readonly record struct PlayHealingItemSound;
public readonly record struct PlayTeleportSound;
#endregion
public readonly record struct PlayGameMusic;
public readonly record struct StopGameMusic;
}
}
}

View File

@@ -0,0 +1,55 @@
using Chickensoft.Introspection;
using Chickensoft.LogicBlocks;
using System;
namespace GameJamDungeon;
public partial class InGameAudioLogic
{
[Meta]
public partial record State : StateLogic<State>
{
public State()
{
OnAttach(() =>
{
var gameEventDepot = Get<IGameEventDepot>();
gameEventDepot.OverworldEntered += OnOverworldEntered;
gameEventDepot.DungeonAThemeAreaEntered += OnDungeonAThemeEntered;
gameEventDepot.MenuScrolled += OnMenuScrolled;
gameEventDepot.MenuBackedOut += OnMenuBackedOut;
gameEventDepot.EquippedItem += OnEquippedItem;
gameEventDepot.InventorySorted += OnInventorySorted;
gameEventDepot.HealingItemConsumed += OnHealingItemConsumed;
gameEventDepot.TeleportEntered += OnTeleportEntered;
});
OnDetach(() =>
{
var gameEventDepot = Get<IGameEventDepot>();
gameEventDepot.OverworldEntered -= OnOverworldEntered;
gameEventDepot.DungeonAThemeAreaEntered -= OnDungeonAThemeEntered;
gameEventDepot.MenuScrolled -= OnMenuScrolled;
gameEventDepot.MenuBackedOut -= OnMenuBackedOut;
gameEventDepot.EquippedItem -= OnEquippedItem;
gameEventDepot.InventorySorted -= OnInventorySorted;
gameEventDepot.TeleportEntered -= OnTeleportEntered;
});
}
private void OnMenuBackedOut() => Output(new Output.PlayMenuBackSound());
private void OnHealingItemConsumed(ConsumableItemStats stats) => Output(new Output.PlayHealingItemSound());
private void OnInventorySorted() => Output(new Output.PlayInventorySortedSound());
private void OnEquippedItem() => Output(new Output.PlayEquipSound());
private void OnOverworldEntered() => Output(new Output.PlayOverworldMusic());
private void OnDungeonAThemeEntered() => Output(new Output.PlayDungeonThemeAMusic());
private void OnMenuScrolled() => Output(new Output.PlayMenuScrollSound());
private void OnTeleportEntered() => Output(new Output.PlayTeleportSound());
}
}

View File

@@ -0,0 +1,13 @@
using Chickensoft.Introspection;
using Chickensoft.LogicBlocks;
namespace GameJamDungeon;
public interface IInGameAudioLogic : ILogicBlock<InGameAudioLogic.State>;
[Meta]
[LogicBlock(typeof(State))]
public partial class InGameAudioLogic :
LogicBlock<InGameAudioLogic.State>, IInGameAudioLogic
{
public override Transition GetInitialState() => To<State>();
}