Added effects manager and two effects to test attached to the player
scene.
This commit is contained in:
parent
1200ac7e32
commit
b4c4a66ce8
19 changed files with 322 additions and 40 deletions
105
scripts/effects/flash_effect.gd
Normal file
105
scripts/effects/flash_effect.gd
Normal file
|
|
@ -0,0 +1,105 @@
|
|||
class_name FlashEffect
|
||||
extends BaseEffect
|
||||
|
||||
## Shader applied to the target sprite during the flash.
|
||||
@export var flash_shader: Shader = preload("res://shaders/flash.gdshader")
|
||||
|
||||
## Color of the flash overlay.
|
||||
@export var flash_color: Color = Color.WHITE
|
||||
|
||||
## How many flash cycles per second.
|
||||
@export_range(0.0, 60.0) var flash_frequency: float = 10.0
|
||||
|
||||
## Fraction of each cycle the flash is visible (0.0–1.0, i.e. duty cycle).
|
||||
@export_range(0.0, 1.0) var flash_length: float = 0.5
|
||||
|
||||
## How the flash blends with the original sprite.
|
||||
@export_enum("Mix", "Additive", "Screen") var blend_mode: int = 0
|
||||
|
||||
## Additional brightness added to the flash color (0.0 = none, 1.0 = double).
|
||||
@export_range(0.0, 1.0) var brightness_boost: float = 0.0
|
||||
|
||||
## Duration of the fade-in at the start of the effect (seconds).
|
||||
@export_range(0.0, 5.0) var start_ease: float = 0.0
|
||||
|
||||
## Easing curve for the fade-in.
|
||||
@export_enum("Linear", "Smooth", "Ease-In", "Ease-Out", "Ease-In-Out") var start_ease_mode: int = 1
|
||||
|
||||
## Duration of the fade-out at the end of the effect (seconds).
|
||||
@export_range(0.0, 5.0) var end_ease: float = 0.0
|
||||
|
||||
## Easing curve for the fade-out.
|
||||
@export_enum("Linear", "Smooth", "Ease-In", "Ease-Out", "Ease-In-Out") var end_ease_mode: int = 1
|
||||
|
||||
var _original_material: Material
|
||||
|
||||
|
||||
func start(target: Node) -> void:
|
||||
super.start(target)
|
||||
if target is CanvasItem:
|
||||
_original_material = target.material
|
||||
var flash_material := ShaderMaterial.new()
|
||||
flash_material.shader = flash_shader
|
||||
flash_material.set_shader_parameter("flash_color", flash_color)
|
||||
flash_material.set_shader_parameter("flash_intensity", 0.0)
|
||||
flash_material.set_shader_parameter("blend_mode", blend_mode)
|
||||
flash_material.set_shader_parameter("brightness_boost", brightness_boost)
|
||||
target.material = flash_material
|
||||
|
||||
|
||||
func process(delta: float, target: Node) -> void:
|
||||
super.process(delta, target)
|
||||
if target.material is ShaderMaterial:
|
||||
var intensity := _compute_intensity(_elapsed)
|
||||
target.material.set_shader_parameter("flash_intensity", intensity)
|
||||
|
||||
|
||||
func stop(target: Node) -> void:
|
||||
if target is CanvasItem:
|
||||
target.material = _original_material
|
||||
|
||||
|
||||
## Compute the combined eased flash intensity for a given elapsed time.
|
||||
## Returns a value 0.0–1.0 where 1.0 means full flash visibility.
|
||||
func _compute_intensity(elapsed: float) -> float:
|
||||
if duration <= 0.0:
|
||||
return 0.0
|
||||
|
||||
# Clamp elapsed to duration to avoid overshoot on the final frame
|
||||
var t: float = min(elapsed, duration)
|
||||
|
||||
# Overall envelope: fade in during start_ease, hold, fade out during end_ease
|
||||
var envelope: float = 1.0
|
||||
if t < start_ease and start_ease > 0.0:
|
||||
envelope = _ease_value(t / start_ease, start_ease_mode)
|
||||
elif t > duration - end_ease and end_ease > 0.0:
|
||||
var fade_progress = (t - (duration - end_ease)) / end_ease
|
||||
envelope = 1.0 - _ease_value(fade_progress, end_ease_mode)
|
||||
|
||||
# Flash pattern: on/off cycling at the given frequency and duty cycle
|
||||
# Each flash pulse also eases in and out for a smoother look
|
||||
var period := 1.0 / flash_frequency if flash_frequency > 0.0 else 1.0
|
||||
var phase := fmod(t, period) / period # 0.0–1.0 position within the current cycle
|
||||
|
||||
var pulse: float = 0.0
|
||||
if phase < flash_length:
|
||||
# Inside the "on" portion of this cycle — ease within the pulse itself
|
||||
var pulse_progress = phase / flash_length if flash_length > 0.0 else 1.0
|
||||
# Ease in for the first half of the pulse (build up), ease out for the second (fade down)
|
||||
if pulse_progress < 0.5:
|
||||
pulse = _ease_value(pulse_progress * 2.0, 2) # Ease-In (build up)
|
||||
else:
|
||||
pulse = _ease_value((1.0 - pulse_progress) * 2.0, 3) # Ease-Out (fade down)
|
||||
|
||||
return envelope * pulse
|
||||
|
||||
|
||||
## Apply easing to a 0.0–1.0 normalized value based on the selected mode.
|
||||
func _ease_value(value: float, mode: int) -> float:
|
||||
match mode:
|
||||
0: return value # Linear
|
||||
1: return smoothstep(0.0, 1.0, value) # Smooth
|
||||
2: return ease(value, -2.0) # Ease-In (accelerating)
|
||||
3: return ease(value, 2.0) # Ease-Out (decelerating)
|
||||
4: return ease(value, 3.0) # Ease-In-Out (S-curve)
|
||||
return value
|
||||
Loading…
Add table
Add a link
Reference in a new issue