using System; using Godot; namespace AceField.Scripts.Effects; public partial class CameraShake : Camera2D { [Export] public float Decay = 0.8f; [Export] public Vector2 MaxOffset = new(100, 75); [Export] public float MaxRoll = 0.0f; [Export] public FastNoiseLite Noise; private float _noiseY = 0.0f; private float _trauma = 0.0f; private int _traumaExponent = 3; public override void _Ready() { GD.Randomize(); Noise.Seed = (int)GD.Randi(); } public override void _Process(double delta) { if (_trauma > 0) { _trauma = Mathf.Max(_trauma - Decay * (float)delta, 0); Shake(); } else if (Offset.X != 0 || Offset.Y != 0 || Rotation != 0) { Mathf.Lerp(Offset.X, 0.0f, 1); Mathf.Lerp(Offset.Y, 0.0f, 1); Mathf.Lerp(Rotation, 0.0f, 1); } } private void Shake() { var amount = Mathf.Pow(_trauma, _traumaExponent); _noiseY++; Rotation = MaxRoll * amount * Noise.GetNoise2D(0, _noiseY); Offset = new Vector2( MaxOffset.X * amount * Noise.GetNoise2D(2000, _noiseY), MaxOffset.Y * amount * Noise.GetNoise2D(3000, _noiseY) ); } public void AddTrauma(float amount) { _trauma = Mathf.Min(_trauma + amount, 1.0f); } public void SetTrauma(float amount) { _trauma = Mathf.Min(amount, 1.0f); } }