Files
tekton/scripts/managers/screen_shake.gd

47 lines
1.5 KiB
GDScript

extends Node
# ScreenShakeManager - Camera-local shake that follows the player
var camera: Camera3D
var shake_intensity: float = 0.0
var shake_duration: float = 0.0
var shake_timer: float = 0.0
var shake_offset: Vector3 = Vector3.ZERO
# Shake presets
const SHAKE_TARGETED: Dictionary = {"intensity": 0.15, "duration": 0.4}
const SHAKE_GOAL_COMPLETE: Dictionary = {"intensity": 0.1, "duration": 0.3}
const SHAKE_LIGHT: Dictionary = {"intensity": 0.05, "duration": 0.2}
func initialize(p_camera: Camera3D):
camera = p_camera
func shake(intensity: float, duration: float) -> void:
"""Trigger a camera shake. Intensity in world units, duration in seconds."""
if intensity <= 0 or duration <= 0:
return
# Take the stronger shake if already active
if shake_timer > 0 and intensity <= shake_intensity:
return
shake_intensity = intensity
shake_duration = duration
shake_timer = duration
func _process(delta: float) -> void:
if not camera or not is_instance_valid(camera):
return
if shake_timer > 0:
shake_timer -= delta
var progress = shake_timer / shake_duration
# Fade out intensity as timer expires
var current_intensity = shake_intensity * progress
# Random offset within intensity range
shake_offset = Vector3(
randf_range(-current_intensity, current_intensity),
randf_range(-current_intensity, current_intensity) * 0.5,
randf_range(-current_intensity, current_intensity)
)
camera.position += shake_offset
else:
shake_offset = Vector3.ZERO