properly fade out the music when finishing a level

This commit is contained in:
Taevas 2025-03-24 18:13:08 +01:00
parent a3e0c4d82d
commit c0aed38065
12 changed files with 80 additions and 87 deletions

View file

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="128" height="128"><rect width="124" height="124" x="2" y="2" fill="#363d52" stroke="#212532" stroke-width="4" rx="14"/><g fill="#fff" transform="translate(12.322 12.322)scale(.101)"><path d="M105 673v33q407 354 814 0v-33z"/><path fill="#478cbf" d="m105 673 152 14q12 1 15 14l4 67 132 10 8-61q2-11 15-15h162q13 4 15 15l8 61 132-10 4-67q3-13 15-14l152-14V427q30-39 56-81-35-59-83-108-43 20-82 47-40-37-88-64 7-51 8-102-59-28-123-42-26 43-46 89-49-7-98 0-20-46-46-89-64 14-123 42 1 51 8 102-48 27-88 64-39-27-82-47-48 49-83 108 26 42 56 81zm0 33v39c0 276 813 276 814 0v-39l-134 12-5 69q-2 10-14 13l-162 11q-12 0-16-11l-10-65H446l-10 65q-4 11-16 11l-162-11q-12-3-14-13l-5-69z"/><path d="M483 600c0 34 58 34 58 0v-86c0-34-58-34-58 0z"/><circle cx="725" cy="526" r="90"/><circle cx="299" cy="526" r="90"/></g><g fill="#414042" transform="translate(12.322 12.322)scale(.101)"><circle cx="307" cy="532" r="60"/><circle cx="717" cy="532" r="60"/></g></svg>

Before

Width:  |  Height:  |  Size: 994 B

View file

@ -1,37 +0,0 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://c4nwhhum2vht5"
path="res://.godot/imported/icon.svg-218a8f2b3041327d8a5756f3a245f83b.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://icon.svg"
dest_files=["res://.godot/imported/icon.svg-218a8f2b3041327d8a5756f3a245f83b.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1
svg/scale=1.0
editor/scale_with_editor_scale=false
editor/convert_colors_with_editor_theme=false

View file

@ -48,19 +48,13 @@ func stop_level() -> void:
$Timer.paused = true $Timer.paused = true
changing_level = true changing_level = true
AudioServer.set_bus_volume_db(0, -5)
await get_tree().create_timer(0.5).timeout
AudioServer.set_bus_volume_db(0, -10)
await get_tree().create_timer(0.5).timeout
AudioServer.set_bus_volume_db(0, -30)
await get_tree().create_timer(0.5).timeout
AudioServer.set_bus_volume_db(0, -50)
await get_tree().create_timer(0.5).timeout
var next_level: PackedScene var next_level: PackedScene
var current_levels = $Levels.get_children(true) var current_levels = $Levels.get_children(true)
if len(current_levels): if len(current_levels):
var current_level = current_levels[0] var current_level: Level = current_levels[0]
current_level.music.fadeOut(2)
await get_tree().create_timer(2).timeout
if current_level.get_meta(\"name\") == \"Base\": if current_level.get_meta(\"name\") == \"Base\":
next_level = forest next_level = forest
elif current_level.get_meta(\"name\") == \"Forest\": elif current_level.get_meta(\"name\") == \"Forest\":

View file

@ -6,7 +6,7 @@
[ext_resource type="PackedScene" uid="uid://cnnvwotv33u1b" path="res://elements/player.tscn" id="2_b00jj"] [ext_resource type="PackedScene" uid="uid://cnnvwotv33u1b" path="res://elements/player.tscn" id="2_b00jj"]
[ext_resource type="PackedScene" uid="uid://cpm3laywhlbq5" path="res://elements/ring.tscn" id="3_hel5x"] [ext_resource type="PackedScene" uid="uid://cpm3laywhlbq5" path="res://elements/ring.tscn" id="3_hel5x"]
[ext_resource type="PackedScene" uid="uid://c77bli40240nk" path="res://elements/sign.tscn" id="4_atq6y"] [ext_resource type="PackedScene" uid="uid://c77bli40240nk" path="res://elements/sign.tscn" id="4_atq6y"]
[ext_resource type="PackedScene" uid="uid://cgt5st4qacruw" path="res://levels/base/music.tscn" id="4_uq42r"] [ext_resource type="PackedScene" uid="uid://dnuakh7n3fuij" path="res://levels/base/music.tscn" id="4_uq42r"]
[node name="Base" type="Node3D"] [node name="Base" type="Node3D"]
script = ExtResource("1_rj40i") script = ExtResource("1_rj40i")

View file

@ -1,4 +1,4 @@
[gd_scene load_steps=8 format=3 uid="uid://cgt5st4qacruw"] [gd_scene load_steps=8 format=3 uid="uid://dnuakh7n3fuij"]
[ext_resource type="AudioStream" uid="uid://b46a7y6vdqd4n" path="res://levels/base/music/hihat-closed.ogg" id="1_shxcq"] [ext_resource type="AudioStream" uid="uid://b46a7y6vdqd4n" path="res://levels/base/music/hihat-closed.ogg" id="1_shxcq"]
[ext_resource type="Script" uid="uid://dgpjhli3hpn0u" path="res://levels/music.gd" id="1_y1f1r"] [ext_resource type="Script" uid="uid://dgpjhli3hpn0u" path="res://levels/music.gd" id="1_y1f1r"]
@ -10,6 +10,7 @@
[node name="Music" type="Node"] [node name="Music" type="Node"]
script = ExtResource("1_y1f1r") script = ExtResource("1_y1f1r")
metadata/_custom_type_script = "uid://dgpjhli3hpn0u"
[node name="AudioStreamPlayer" type="AudioStreamPlayer" parent="."] [node name="AudioStreamPlayer" type="AudioStreamPlayer" parent="."]
stream = ExtResource("1_shxcq") stream = ExtResource("1_shxcq")

View file

@ -2,7 +2,7 @@
[ext_resource type="Script" uid="uid://w3fetao1pegm" path="res://levels/level.gd" id="1_ifscd"] [ext_resource type="Script" uid="uid://w3fetao1pegm" path="res://levels/level.gd" id="1_ifscd"]
[ext_resource type="PackedScene" uid="uid://b6gnffoboc5j5" path="res://levels/night/environment.tscn" id="2_v6rg2"] [ext_resource type="PackedScene" uid="uid://b6gnffoboc5j5" path="res://levels/night/environment.tscn" id="2_v6rg2"]
[ext_resource type="PackedScene" uid="uid://q7frlnx37gv6" path="res://levels/night/music.tscn" id="3_fb0ct"] [ext_resource type="PackedScene" uid="uid://drfy3vhe6skp1" path="res://levels/night/music.tscn" id="3_fb0ct"]
[ext_resource type="PackedScene" uid="uid://cnnvwotv33u1b" path="res://elements/player.tscn" id="4_ge8id"] [ext_resource type="PackedScene" uid="uid://cnnvwotv33u1b" path="res://elements/player.tscn" id="4_ge8id"]
[ext_resource type="PackedScene" uid="uid://cpm3laywhlbq5" path="res://elements/ring.tscn" id="5_j060p"] [ext_resource type="PackedScene" uid="uid://cpm3laywhlbq5" path="res://elements/ring.tscn" id="5_j060p"]

View file

@ -3,7 +3,7 @@
[ext_resource type="PackedScene" uid="uid://w4h8ip754qnb" path="res://levels/forest/environment.tscn" id="1_7clrg"] [ext_resource type="PackedScene" uid="uid://w4h8ip754qnb" path="res://levels/forest/environment.tscn" id="1_7clrg"]
[ext_resource type="Script" uid="uid://w3fetao1pegm" path="res://levels/level.gd" id="1_fdxcj"] [ext_resource type="Script" uid="uid://w3fetao1pegm" path="res://levels/level.gd" id="1_fdxcj"]
[ext_resource type="PackedScene" uid="uid://cnnvwotv33u1b" path="res://elements/player.tscn" id="2_mjogx"] [ext_resource type="PackedScene" uid="uid://cnnvwotv33u1b" path="res://elements/player.tscn" id="2_mjogx"]
[ext_resource type="PackedScene" uid="uid://dp8nvfm55te85" path="res://levels/forest/music.tscn" id="3_n1xsx"] [ext_resource type="PackedScene" uid="uid://cakmsiye3hjfe" path="res://levels/forest/music.tscn" id="3_n1xsx"]
[ext_resource type="PackedScene" uid="uid://cpm3laywhlbq5" path="res://elements/ring.tscn" id="4_p8yhq"] [ext_resource type="PackedScene" uid="uid://cpm3laywhlbq5" path="res://elements/ring.tscn" id="4_p8yhq"]
[ext_resource type="PackedScene" uid="uid://da6lkdiskdh8v" path="res://elements/tree.tscn" id="6_1e514"] [ext_resource type="PackedScene" uid="uid://da6lkdiskdh8v" path="res://elements/tree.tscn" id="6_1e514"]
[ext_resource type="PackedScene" uid="uid://c77bli40240nk" path="res://elements/sign.tscn" id="6_ifogr"] [ext_resource type="PackedScene" uid="uid://c77bli40240nk" path="res://elements/sign.tscn" id="6_ifogr"]

View file

@ -1,4 +1,4 @@
[gd_scene load_steps=8 format=3 uid="uid://dp8nvfm55te85"] [gd_scene load_steps=8 format=3 uid="uid://cakmsiye3hjfe"]
[ext_resource type="Script" uid="uid://dgpjhli3hpn0u" path="res://levels/music.gd" id="1_whsrg"] [ext_resource type="Script" uid="uid://dgpjhli3hpn0u" path="res://levels/music.gd" id="1_whsrg"]
[ext_resource type="AudioStream" uid="uid://pn2b2f3egpck" path="res://levels/forest/music/dong2.ogg" id="2_pm2p2"] [ext_resource type="AudioStream" uid="uid://pn2b2f3egpck" path="res://levels/forest/music/dong2.ogg" id="2_pm2p2"]
@ -10,6 +10,7 @@
[node name="Music" type="Node"] [node name="Music" type="Node"]
script = ExtResource("1_whsrg") script = ExtResource("1_whsrg")
metadata/_custom_type_script = "uid://dgpjhli3hpn0u"
[node name="AudioStreamPlayer" type="AudioStreamPlayer" parent="."] [node name="AudioStreamPlayer" type="AudioStreamPlayer" parent="."]
stream = ExtResource("2_pm2p2") stream = ExtResource("2_pm2p2")

View file

@ -1,20 +1,19 @@
class_name Level
extends Node3D extends Node3D
var music: Music
var velocity: float = 0.0 var velocity: float = 0.0
var rings_count = 72727 var rings_count = 72727
var finished_rings_count = 0 var finished_rings_count = 0
var rings: Array[Node] = [] var rings: Array[Node] = []
var stream_players: Array[AudioStreamPlayer] = []
func _ready() -> void: func _ready() -> void:
var music_node = get_node("Music") var children = get_children()
assert(is_instance_valid(music_node), self.name + " has no music!") for child in children:
var music = music_node.get_children() if is_instance_of(child, Music):
for music_player in music: music = child
if music_player is AudioStreamPlayer: assert(is_instance_valid(music), self.name + " has no music!")
stream_players.push_back(music_player)
var rings_node = get_node("Rings") var rings_node = get_node("Rings")
assert(is_instance_valid(rings_node), self.name + " has no rings!") assert(is_instance_valid(rings_node), self.name + " has no rings!")
@ -33,19 +32,4 @@ func do_we_end_yet():
func _process(delta: float) -> void: func _process(delta: float) -> void:
var sphere = $Player/Sphere var sphere = $Player/Sphere
velocity = abs(sphere.linear_velocity.x) + abs(sphere.linear_velocity.y) velocity = abs(sphere.linear_velocity.x) + abs(sphere.linear_velocity.y)
var instruments_needed = floor(velocity / 8) music.adaptInstrumentsToVelocity(velocity, delta)
var instruments_playing = stream_players.filter(func(p: AudioStreamPlayer): return p.volume_db > -50)
for index_p in len(instruments_playing):
var playing = instruments_playing[index_p]
if index_p + 1 > instruments_needed:
playing.volume_db = max(playing.volume_db - (delta * 32), -50)
elif playing.volume_db <= 0:
playing.volume_db = min(playing.volume_db + (delta * 8), 0)
if instruments_needed > len(instruments_playing):
var instruments_not_playing = stream_players.filter(func(p: AudioStreamPlayer): return p.volume_db <= -50)
if len(instruments_not_playing):
var to_play = instruments_not_playing.pick_random()
if is_instance_valid(to_play):
to_play.volume_db = min(to_play.volume_db + (delta * 16), 0)

View file

@ -1,15 +1,65 @@
class_name Music
extends Node extends Node
## While the instruments are manipulated individually to match the gameplay,
## they are all regrouped in a single bus dedicated to this specific music.
## So we also manipulate the bus itself for the purposes of applying
## audio balance and settings and the such more efficiently.
var bus_index: int = -1
var instruments: Array[AudioStreamPlayer] = []
func _ready() -> void: func _ready() -> void:
var players = get_children() bus_index = AudioServer.get_bus_index(self.name)
for player in players: if bus_index == -1:
if player is AudioStreamPlayer: AudioServer.add_bus()
player.volume_db = -50 AudioServer.set_bus_name(AudioServer.bus_count - 1, self.name)
var stream: AudioStreamOggVorbis = player.stream bus_index = AudioServer.get_bus_index(self.name)
var current_effects = AudioServer.get_bus_effect_count(bus_index)
for i in current_effects:
AudioServer.remove_bus_effect(bus_index, i)
var children = get_children()
for child in children:
if child is AudioStreamPlayer:
instruments.push_back(child)
child.bus = AudioServer.get_bus_name(bus_index)
child.volume_db = -50
var stream: AudioStreamOggVorbis = child.stream
if stream is AudioStreamOggVorbis: if stream is AudioStreamOggVorbis:
stream.loop = true stream.loop = true
stream.bpm = 124 stream.bpm = 124
for player in players: for instrument in instruments:
if player is AudioStreamPlayer: if instrument is AudioStreamPlayer:
player.play() instrument.play()
func changeVolume(db: float) -> void:
AudioServer.set_bus_volume_db(bus_index, db)
func adaptInstrumentsToVelocity(velocity: float, delta: float) -> void:
var instruments_needed = floor(velocity / 8)
var instruments_playing = instruments.filter(func(i: AudioStreamPlayer): return i.volume_db > -50)
for index_p in len(instruments_playing):
var playing = instruments_playing[index_p]
if index_p + 1 > instruments_needed:
playing.volume_db = max(playing.volume_db - (delta * 32), -50)
elif playing.volume_db <= 0:
playing.volume_db = min(playing.volume_db + (delta * 8), 0)
if instruments_needed > len(instruments_playing):
var instruments_not_playing = instruments.filter(func(i: AudioStreamPlayer): return i.volume_db <= -50)
if len(instruments_not_playing):
var to_play = instruments_not_playing.pick_random()
if is_instance_valid(to_play):
to_play.volume_db = min(to_play.volume_db + (delta * 16), 0)
func fadeOut(seconds: float) -> void:
var tween: Tween = create_tween()
# https://github.com/godotengine/godot/issues/32882
AudioServer.add_bus_effect(bus_index, AudioEffectAmplify.new())
var effect_index: int = AudioServer.get_bus_effect_count(bus_index) - 1
var effect: AudioEffectAmplify = AudioServer.get_bus_effect(bus_index, effect_index)
tween.tween_property(effect, "volume_linear", 0, seconds)

View file

@ -1,7 +1,7 @@
[gd_scene load_steps=9 format=3 uid="uid://c2rlx31om4gey"] [gd_scene load_steps=9 format=3 uid="uid://c2rlx31om4gey"]
[ext_resource type="Script" uid="uid://w3fetao1pegm" path="res://levels/level.gd" id="1_3m1pa"] [ext_resource type="Script" uid="uid://w3fetao1pegm" path="res://levels/level.gd" id="1_3m1pa"]
[ext_resource type="PackedScene" uid="uid://q7frlnx37gv6" path="res://levels/night/music.tscn" id="1_npc74"] [ext_resource type="PackedScene" uid="uid://drfy3vhe6skp1" path="res://levels/night/music.tscn" id="1_npc74"]
[ext_resource type="PackedScene" uid="uid://cnnvwotv33u1b" path="res://elements/player.tscn" id="2_bc1ig"] [ext_resource type="PackedScene" uid="uid://cnnvwotv33u1b" path="res://elements/player.tscn" id="2_bc1ig"]
[ext_resource type="PackedScene" uid="uid://b6gnffoboc5j5" path="res://levels/night/environment.tscn" id="2_wintp"] [ext_resource type="PackedScene" uid="uid://b6gnffoboc5j5" path="res://levels/night/environment.tscn" id="2_wintp"]
[ext_resource type="PackedScene" uid="uid://cpm3laywhlbq5" path="res://elements/ring.tscn" id="4_brcr0"] [ext_resource type="PackedScene" uid="uid://cpm3laywhlbq5" path="res://elements/ring.tscn" id="4_brcr0"]

View file

@ -1,4 +1,4 @@
[gd_scene load_steps=8 format=3 uid="uid://q7frlnx37gv6"] [gd_scene load_steps=8 format=3 uid="uid://drfy3vhe6skp1"]
[ext_resource type="Script" uid="uid://dgpjhli3hpn0u" path="res://levels/music.gd" id="1_ok6lg"] [ext_resource type="Script" uid="uid://dgpjhli3hpn0u" path="res://levels/music.gd" id="1_ok6lg"]
[ext_resource type="AudioStream" uid="uid://dcgmuddvkcw6" path="res://levels/night/music/hihat-closed.ogg" id="2_oeg0c"] [ext_resource type="AudioStream" uid="uid://dcgmuddvkcw6" path="res://levels/night/music/hihat-closed.ogg" id="2_oeg0c"]
@ -10,6 +10,7 @@
[node name="Music" type="Node"] [node name="Music" type="Node"]
script = ExtResource("1_ok6lg") script = ExtResource("1_ok6lg")
metadata/_custom_type_script = "uid://dgpjhli3hpn0u"
[node name="AudioStreamPlayer" type="AudioStreamPlayer" parent="."] [node name="AudioStreamPlayer" type="AudioStreamPlayer" parent="."]
stream = ExtResource("2_oeg0c") stream = ExtResource("2_oeg0c")