Set up framework for more advance pickup behaviours.
This commit is contained in:
parent
a0df0be862
commit
935b61bd3b
16 changed files with 485 additions and 20 deletions
132
scripts/pickups/pickup_behavior_controller.gd
Normal file
132
scripts/pickups/pickup_behavior_controller.gd
Normal file
|
|
@ -0,0 +1,132 @@
|
|||
class_name PickupBehaviorController extends Area2D
|
||||
|
||||
## Controls visual movement (bob, shake) and drift of a pickup.
|
||||
## Attach to the root Area2D node of your pickup scene.
|
||||
|
||||
@export var behavior: PickupBehavior
|
||||
@export var drift_behavior: PickupDriftBehavior
|
||||
|
||||
|
||||
var _icon_node: TextureRect
|
||||
var _spawn_position: Vector2 = Vector2.ZERO
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
# Find the runtime-added icon node.
|
||||
for child in get_children():
|
||||
if child is TextureRect:
|
||||
_icon_node = child as TextureRect
|
||||
break
|
||||
# Capture the initial spawn position.
|
||||
_spawn_position = global_position
|
||||
|
||||
if behavior != null:
|
||||
behavior.start()
|
||||
|
||||
|
||||
func _process(delta: float) -> void:
|
||||
if behavior == null or drift_behavior == null:
|
||||
return
|
||||
|
||||
var alpha: float = behavior.process(delta)
|
||||
|
||||
if _icon_node != null:
|
||||
_icon_node.visible = alpha > 0.01
|
||||
if behavior != null and behavior.fade_in_duration > 0 and _icon_node is CanvasItem:
|
||||
_icon_node.modulate.a = alpha
|
||||
|
||||
var offset := _compute_animation_offset()
|
||||
var drift_offset := _compute_drift_offset()
|
||||
|
||||
position = _spawn_position + Vector2(drift_offset.x, drift_offset.y)
|
||||
|
||||
if _icon_node != null:
|
||||
_icon_node.position = offset
|
||||
|
||||
|
||||
func _compute_animation_offset() -> Vector2:
|
||||
# Returns the bob + shake offset applied to the icon node.
|
||||
var result := Vector2.ZERO
|
||||
|
||||
if behavior == null:
|
||||
return result
|
||||
|
||||
# Bob (vertical oscillation).
|
||||
if behavior.bob_enabled:
|
||||
var bob_angle := _elapsed_time() * TAU * behavior.bob_frequency
|
||||
result.y += sin(bob_angle) * behavior.bob_amplitude
|
||||
|
||||
# Shake (subtle jitter).
|
||||
if behavior.shake_enabled:
|
||||
var shake_angle := _elapsed_time() * TAU * behavior.shake_frequency
|
||||
result.x += sin(shake_angle) * behavior.shake_amplitude
|
||||
|
||||
return result
|
||||
|
||||
|
||||
func _compute_drift_offset() -> Vector2:
|
||||
# Returns the global drift position offset from initial spawn position.
|
||||
if drift_behavior == null:
|
||||
return Vector2.ZERO
|
||||
|
||||
match drift_behavior.drift_type:
|
||||
PickupDriftBehavior.DriftType.STATIONARY:
|
||||
return Vector2.ZERO
|
||||
|
||||
PickupDriftBehavior.DriftType.SINE_WAVE:
|
||||
var t := _elapsed_time() * drift_behavior.wave_frequency
|
||||
var travel_speed: float = drift_behavior.drift_speed
|
||||
if drift_behavior.reverse_direction:
|
||||
travel_speed *= -1.0
|
||||
|
||||
var offset := Vector2.ZERO
|
||||
if drift_behavior.drift_along_x:
|
||||
# Travels along X; waves on Y.
|
||||
offset.x = travel_speed * _elapsed_time()
|
||||
offset.y = sin(t + drift_behavior.phase_offset) * drift_behavior.wave_amplitude
|
||||
else:
|
||||
# Travels along Y; waves on X.
|
||||
offset.y = travel_speed * _elapsed_time()
|
||||
offset.x = sin(t + drift_behavior.phase_offset) * drift_behavior.wave_amplitude
|
||||
return offset
|
||||
|
||||
PickupDriftBehavior.DriftType.LEAF_FALL:
|
||||
var leaf_t := _elapsed_time() * drift_behavior.wave_frequency
|
||||
var travel_speed: float = drift_behavior.fall_speed
|
||||
if drift_behavior.reverse_direction:
|
||||
travel_speed *= -1.0
|
||||
|
||||
var offset := Vector2.ZERO
|
||||
if drift_behavior.drift_along_x:
|
||||
# Travels along X; waves on Y.
|
||||
offset.x = travel_speed * _elapsed_time()
|
||||
offset.y = sin(leaf_t + drift_behavior.phase_offset) * drift_behavior.wave_amplitude
|
||||
else:
|
||||
# Travels along Y; waves on X.
|
||||
offset.y = travel_speed * _elapsed_time()
|
||||
offset.x = sin(leaf_t + drift_behavior.phase_offset) * drift_behavior.wave_amplitude
|
||||
return offset
|
||||
|
||||
PickupDriftBehavior.DriftType.DIAGONAL:
|
||||
var dir: float = 1.0 if drift_behavior.diagonal_forward else -1.0
|
||||
if drift_behavior.reverse_direction:
|
||||
dir *= -1.0
|
||||
|
||||
var offset := Vector2.ZERO
|
||||
if drift_behavior.drift_along_x:
|
||||
# Travels along X; secondary on Y.
|
||||
offset.x = dir * drift_behavior.drift_speed * _elapsed_time()
|
||||
offset.y = dir * (drift_behavior.drift_speed * 0.5) * _elapsed_time()
|
||||
else:
|
||||
# Travels along Y; secondary on X.
|
||||
offset.y = dir * drift_behavior.drift_speed * _elapsed_time()
|
||||
offset.x = dir * (drift_behavior.drift_speed * 0.5) * _elapsed_time()
|
||||
return offset
|
||||
|
||||
return Vector2.ZERO
|
||||
|
||||
|
||||
func _elapsed_time() -> float:
|
||||
if behavior == null:
|
||||
return 0.0
|
||||
return behavior._elapsed
|
||||
1
scripts/pickups/pickup_behavior_controller.gd.uid
Normal file
1
scripts/pickups/pickup_behavior_controller.gd.uid
Normal file
|
|
@ -0,0 +1 @@
|
|||
uid://c4a7husvaq2eo
|
||||
Loading…
Add table
Add a link
Reference in a new issue