projektluzid/3rdparty/basic_bars_example.gd
2025-06-18 19:36:23 +02:00

66 lines
2.1 KiB
GDScript

extends Control
@export var audio_player: AudioStreamPlayer
var spectrum_instance
const NUM_BARS = 64 # Number of frequency bands to display
const MAX_FREQ = 1000 # Frequency range to analyze
var bars = []
@export var shuffle_freq = false
@export var flip_y = false
var color_gradient := Gradient.new() # Dynamic color transitions
func _ready():
position = Vector2(0, get_viewport_rect().size.y - 150)
# Set up color gradient (Blue → Purple → Red)
scale = Vector2(1.5, 1.5)
color_gradient.add_point(0.0, Color(0.2, 1.0, 0.8)) # Cyan
color_gradient.add_point(0.5, Color(0.6, 0.2, 1.0)) # Purple
color_gradient.add_point(1.0, Color(1.0, 0.2, 0.2)) # Red
spectrum_instance = AudioServer.get_bus_effect_instance(1, 0) # Bus 1, Effect 0
create_bars()
func create_bars():
for i in range(NUM_BARS):
var bar = ColorRect.new()
bar.color = Color(0.2, 0.8, 1.0)
# Set anchors so position/size are relative to top-left
bar.set_anchors_preset(Control.PRESET_BOTTOM_LEFT)
# Position each bar starting from the bottom left
bar.rect_position = Vector2(i * 10, 0) # X is offset, Y = 0 at bottom
bar.rect_size = Vector2(8, 1) # Start with a minimal height
add_child(bar)
bars.append(bar)
func _process(delta):
if not spectrum_instance:
return
var max_freq_amp = bars.reduce(func(m, b): return b if b.rect_size.y > m.rect_size.y else m).rect_size.y
for i in range(NUM_BARS):
var freq_start = (i * MAX_FREQ) / NUM_BARS
var freq_end = ((i + 1) * MAX_FREQ) / NUM_BARS
var magnitude = spectrum_instance.get_magnitude_for_frequency_range(freq_start, freq_end).length()
var target_height = magnitude * 1000 * 2
bars[i].rect_size.y = lerp(bars[i].rect_size.y, target_height, 0.2)
bars[i].rect_position.y = -bars[i].rect_size.y # Move bar so it grows upward
# Smooth animation
var intensity = bars[i].rect_size.y / (max_freq_amp * 1.0) if max_freq_amp > 0 else 0.0
# intensity *= 1000
intensity = clamp(intensity, 0.0, 1.0) # Keep within valid range
# Get dynamic color from gradient
var new_color = color_gradient.sample(intensity)
bars[i].color = new_color
if flip_y:
bars[i].scale.y = -1
if shuffle_freq:
bars.shuffle()