86 lines
2.4 KiB
GDScript
86 lines
2.4 KiB
GDScript
extends Node
|
|
## Klänge ohne Dateien. Die kurzen Wellen werden beim Start berechnet - so wie
|
|
## Würfel und Münzen gemalt statt geladen werden. Auf dem Spielserver ohne
|
|
## Tongerät spielt das ins Leere, stört aber nicht.
|
|
|
|
const RATE := 22050
|
|
|
|
var _wuerfel: AudioStreamWAV
|
|
var _muenze: AudioStreamWAV
|
|
var _becher: AudioStreamWAV
|
|
var _chime: AudioStreamWAV
|
|
var _rng := RandomNumberGenerator.new()
|
|
|
|
|
|
func _ready() -> void:
|
|
_rng.randomize()
|
|
# Klack: Rauschen, das sofort wieder weg ist.
|
|
_wuerfel = _wav(0.07, func(t: float) -> float:
|
|
return _rausch() * exp(-t * 60.0))
|
|
# Klirren: drei unharmonische Töne, die langsam ausklingen.
|
|
_muenze = _wav(0.35, func(t: float) -> float:
|
|
return (sin(TAU * 2600.0 * t) + 0.5 * sin(TAU * 4100.0 * t)
|
|
+ 0.3 * sin(TAU * 6300.0 * t)) / 1.8 * exp(-t * 9.0))
|
|
# Dumpfer Schlag: tiefer Ton plus kurzes Rauschen.
|
|
_becher = _wav(0.14, func(t: float) -> float:
|
|
return sin(TAU * 110.0 * t) * exp(-t * 22.0) + _rausch() * 0.3 * exp(-t * 80.0))
|
|
# Zwei Töne aufwärts - für den Gewinn.
|
|
_chime = _wav(0.55, func(t: float) -> float:
|
|
var a := sin(TAU * 880.0 * t) * exp(-t * 4.0)
|
|
var b := 0.0
|
|
if t > 0.14:
|
|
b = sin(TAU * 1320.0 * (t - 0.14)) * exp(-(t - 0.14) * 4.0)
|
|
return (a + b) * 0.5)
|
|
|
|
|
|
func _rausch() -> float:
|
|
return _rng.randf_range(-1.0, 1.0)
|
|
|
|
|
|
func _wav(sek: float, f: Callable) -> AudioStreamWAV:
|
|
var n := int(RATE * sek)
|
|
var data := PackedByteArray()
|
|
data.resize(n * 2)
|
|
for i in n:
|
|
var v: float = clampf(f.call(float(i) / RATE), -1.0, 1.0)
|
|
data.encode_s16(i * 2, int(v * 32000.0))
|
|
var w := AudioStreamWAV.new()
|
|
w.format = AudioStreamWAV.FORMAT_16_BITS
|
|
w.mix_rate = RATE
|
|
w.data = data
|
|
return w
|
|
|
|
|
|
func _spiel(w: AudioStreamWAV, db: float, pitch := 1.0) -> void:
|
|
var p := AudioStreamPlayer.new()
|
|
p.stream = w
|
|
p.volume_db = db
|
|
p.pitch_scale = pitch
|
|
add_child(p)
|
|
p.finished.connect(p.queue_free)
|
|
p.play()
|
|
|
|
|
|
## Mehrere Würfel fallen: ein paar Klacker kurz hintereinander, verschieden hoch.
|
|
func wuerfel(anzahl := 5) -> void:
|
|
for i in mini(anzahl, 8):
|
|
await get_tree().create_timer(_rng.randf_range(0.0, 0.35)).timeout
|
|
_spiel(_wuerfel, -8.0, _rng.randf_range(0.8, 1.3))
|
|
|
|
|
|
## Ein kurzer heller Klick - je gezähltem Würfel einer.
|
|
func tick() -> void:
|
|
_spiel(_wuerfel, -14.0, 2.2)
|
|
|
|
|
|
func muenze() -> void:
|
|
_spiel(_muenze, -6.0, _rng.randf_range(0.95, 1.05))
|
|
|
|
|
|
func becher() -> void:
|
|
_spiel(_becher, -3.0)
|
|
|
|
|
|
func chime() -> void:
|
|
_spiel(_chime, -8.0)
|