111 lines
2.7 KiB
GDScript
111 lines
2.7 KiB
GDScript
#@tool
|
|
#@icon(icon_path: String)
|
|
class_name Musician
|
|
extends AnimatedSprite2D
|
|
## Documentation comments
|
|
|
|
#signal
|
|
#enum
|
|
#const
|
|
|
|
@export_group("Input Textures")
|
|
@export var solid_texture: Texture2D
|
|
@export var outline_texture: Texture2D
|
|
|
|
@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
|
|
var is_active: bool = false
|
|
var is_boosted: bool
|
|
var is_over_boosted: bool = false
|
|
var seconds_per_beat: float
|
|
var useconds_per_beat: int
|
|
|
|
@onready var audio: AudioStreamPlayer2D = %Audio
|
|
@onready var light: PointLight2D = %Light
|
|
@onready var occluder: LightOccluder2D = %Occluder
|
|
@onready var input_prompt: Sprite2D = %InputPrompt
|
|
@onready var volume_bar: ProgressBar = %VolumeBar
|
|
@onready var boost_timer: Timer = %BoostTimer
|
|
|
|
## OVERRIDES
|
|
|
|
func _ready() -> void:
|
|
light.visible = false
|
|
_connect_signals()
|
|
|
|
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)
|
|
|
|
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
|
|
|
|
func _unhandled_input(event: InputEvent) -> void:
|
|
if event.is_action_pressed("play_pause"):
|
|
play_pause()
|
|
if event.is_action_pressed(input_action):
|
|
boost_volume()
|
|
|
|
## CORE
|
|
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:
|
|
if is_active:
|
|
play("idle")
|
|
audio.stop()
|
|
light.visible = false
|
|
is_active = false
|
|
input_prompt.texture = outline_texture
|
|
else:
|
|
play("default")
|
|
audio.play()
|
|
if not is_boosted:
|
|
is_boosted = true
|
|
boost_timer.start()
|
|
light.visible = true
|
|
is_active = true
|
|
input_prompt.texture = solid_texture
|
|
|
|
## PRIVATE/HELPER
|
|
|
|
func _connect_signals() -> void:
|
|
boost_timer.connect("timeout", on_boost_timer_timeout)
|
|
audio.connect("finished", play_pause)
|
|
|
|
## RECEIVERS
|
|
|
|
func on_boost_timer_timeout() -> void:
|
|
print("boost over")
|
|
boost_timer.stop()
|
|
is_boosted = false
|
|
is_over_boosted = false
|
|
audio.pitch_scale = 1.0
|
|
|
|
## SETTERS/GETTERS
|