conductor/scripts/musician.gd

111 lines
2.7 KiB
GDScript3
Raw Normal View History

2026-03-13 21:52:21 +00:00
#@tool
#@icon(icon_path: String)
class_name Musician
extends AnimatedSprite2D
## Documentation comments
2026-03-15 03:57:31 +00:00
#signal
#enum
#const
@export_group("Input Textures")
@export var solid_texture: Texture2D
@export var outline_texture: Texture2D
2026-03-15 20:49:01 +00:00
@export var beats_per_boost: int = 4
@export var song_tempo: int = 120
@export_enum("sample", "viol", "cello", "bass", "ready") var input_action: String
var decay_length: float
var decay_rate: float
2026-03-13 21:52:21 +00:00
var is_active: bool = false
2026-03-15 20:49:01 +00:00
var is_boosted: bool
var is_over_boosted: bool = false
var seconds_per_beat: float
var useconds_per_beat: int
2026-03-13 21:52:21 +00:00
@onready var audio: AudioStreamPlayer2D = %Audio
@onready var light: PointLight2D = %Light
@onready var occluder: LightOccluder2D = %Occluder
@onready var input_prompt: Sprite2D = %InputPrompt
2026-03-15 20:49:01 +00:00
@onready var volume_bar: ProgressBar = %VolumeBar
@onready var boost_timer: Timer = %BoostTimer
2026-03-13 21:52:21 +00:00
## OVERRIDES
func _ready() -> void:
light.visible = false
2026-03-15 20:49:01 +00:00
_connect_signals()
2026-03-15 20:49:01 +00:00
input_prompt.texture = outline_texture
seconds_per_beat = 60.0/float(song_tempo)
decay_length = beats_per_boost * seconds_per_beat
print("this musician's boosts will last %s seconds" % decay_length)
boost_timer.wait_time = decay_length
decay_rate = 80.0 / decay_length
print("so the volume will drop by %s db per second" % decay_rate)
2026-03-13 21:52:21 +00:00
2026-03-15 20:49:01 +00:00
func _process(delta: float) -> void:
if is_over_boosted:
distort_pitch(sin(Time.get_ticks_msec()))
if is_active and not is_boosted:
drop_volume(decay_rate * delta)
volume_bar.value = audio.volume_db
2026-03-13 21:52:21 +00:00
2026-03-15 20:49:01 +00:00
func _unhandled_input(event: InputEvent) -> void:
if event.is_action_pressed("play_pause"):
play_pause()
if event.is_action_pressed(input_action):
boost_volume()
2026-03-13 21:52:21 +00:00
## CORE
2026-03-15 20:49:01 +00:00
func boost_volume() -> void:
if is_boosted:
is_over_boosted = true
audio.volume_db = 0.0
is_boosted = true
boost_timer.start()
func distort_pitch(distortion: float) -> void:
print("distorting by %s" % distortion)
audio.pitch_scale += distortion
print("pitch scale is %s" % audio.pitch_scale)
func drop_volume(d_r: float) -> void:
audio.volume_db -= d_r
func play_pause() -> void:
2026-03-13 21:52:21 +00:00
if is_active:
play("idle")
2026-03-15 20:49:01 +00:00
audio.stop()
2026-03-13 21:52:21 +00:00
light.visible = false
is_active = false
input_prompt.texture = outline_texture
2026-03-13 21:52:21 +00:00
else:
play("default")
2026-03-15 20:49:01 +00:00
audio.play()
if not is_boosted:
is_boosted = true
boost_timer.start()
2026-03-13 21:52:21 +00:00
light.visible = true
is_active = true
input_prompt.texture = solid_texture
2026-03-13 21:52:21 +00:00
## PRIVATE/HELPER
2026-03-15 20:49:01 +00:00
func _connect_signals() -> void:
boost_timer.connect("timeout", on_boost_timer_timeout)
audio.connect("finished", play_pause)
2026-03-13 21:52:21 +00:00
## RECEIVERS
2026-03-15 20:49:01 +00:00
func on_boost_timer_timeout() -> void:
print("boost over")
boost_timer.stop()
is_boosted = false
is_over_boosted = false
audio.pitch_scale = 1.0
2026-03-13 21:52:21 +00:00
## SETTERS/GETTERS