49 lines
1.5 KiB
GDScript
49 lines
1.5 KiB
GDScript
class_name ShakingCamera extends Camera2D
|
|
|
|
|
|
@export var decay = 0.8 # How quickly the shaking stops [0, 1].
|
|
@export var max_offset = Vector2(100, 75) # Maximum hor/ver shake in pixels.
|
|
@export var max_roll = 0.1 # Maximum rotation in radians (use sparingly).
|
|
@export var target = NodePath()
|
|
@onready var noise = FastNoiseLite.new()
|
|
|
|
var noise_y = 0
|
|
|
|
var traumax = 0.0 # Current shake strength.
|
|
var traumay = 0.0 # Current shake strength.
|
|
var trauma_power = 2 # Trauma exponent. Use [2, 3].
|
|
|
|
func _ready():
|
|
randomize()
|
|
noise.noise_type = FastNoiseLite.TYPE_PERLIN
|
|
noise.seed = 0982309586286872365
|
|
|
|
func add_trauma(amount):
|
|
traumax = min(traumax + amount, 1.0)
|
|
traumay = min(traumay + amount, 1.0)
|
|
func add_trauma_x(amount):
|
|
traumax = min(traumax + amount, 1.0)
|
|
func add_trauma_y(amount):
|
|
traumay = min(traumay + amount, 1.0)
|
|
|
|
func _process(delta):
|
|
if target:
|
|
global_position = get_node(target).global_position
|
|
var goshake = traumax or traumay
|
|
if traumax:
|
|
traumax = max(traumax - decay * delta, 0)
|
|
if traumay:
|
|
traumay = max(traumay - decay * delta, 0)
|
|
if goshake:
|
|
shake()
|
|
|
|
func shake():
|
|
noise_y += 1
|
|
var amountx = pow(traumax, trauma_power)
|
|
var amounty = pow(traumay, trauma_power)
|
|
if traumax:
|
|
rotation = max_roll * amountx * noise.get_noise_2d(noise.seed, noise_y)
|
|
offset.x = max_offset.x * amountx * noise.get_noise_2d(noise.seed*2, noise_y)
|
|
if traumay:
|
|
offset.y = max_offset.y * amounty * noise.get_noise_2d(noise.seed*3, noise_y)
|