hadean-godot/Scripts/CursorPool.gd

133 lines
5.7 KiB
GDScript

extends Node2D
class_name CursorPool
enum AnimationState {
Normal, # lerps box center and size to desired.
Exploding, # Normal but diff lerp speeds.
Area, # lerps each box side to desired box side
Fading, # standard box motion, opacity fades slowly.
}
class Cursor:
var box: Rect2
var opacity: float
var desired_box: Rect2
var desired_opacity: float
var color: Color
var animation: AnimationState = AnimationState.Normal
var cursors: Array[Cursor] = []
var current_cursor: Cursor = null
func new_cursor(color: Color) -> Cursor:
var cursor = Cursor.new()
cursors.append(cursor)
if cursors.size() > 10: cursors.remove_at(0)
cursor.box = get_viewport_rect()
cursor.box.size = Vector2.ONE * max(cursor.box.size.x, cursor.box.size.y)
cursor.box = Rect2(cursor.box.position + cursor.box.size / -2.0, cursor.box.size).grow(100)
cursor.opacity = -2.0
cursor.animation = AnimationState.Normal
cursor.desired_box = cursor.box
cursor.desired_opacity = 1.0
cursor.color = color
current_cursor = cursor
return cursor
# cursor removal type beats.
func fade_out() -> void:
if current_cursor == null: return
current_cursor.animation = AnimationState.Fading
current_cursor.desired_opacity = 0.0
func explode() -> void:
if current_cursor == null: return
current_cursor.animation = AnimationState.Exploding
current_cursor.desired_box = current_cursor.desired_box.grow(10)
current_cursor.desired_opacity = 0.0
# override / util
func _process(delta) -> void:
for d in cursors:
match d.animation:
AnimationState.Normal: _update_display_animation_active(d, delta)
AnimationState.Exploding: _update_display_animation_exploding(d, delta)
AnimationState.Fading: _update_display_animation_fading(d, delta)
AnimationState.Area: _update_display_animation_area(d, delta)
queue_redraw()
func _draw():
for d in cursors:
draw_rect(d.box, _lerp_opacity(d.color, d.opacity), true)
func _lerp_opacity(c: Color, t: float) -> Color:
return Color(c.r, c.g, c.b, c.a * t)
# === Display Animations
func _update_display_animation_active(d: Cursor, delta):
var old_size = d.box.size
var desired_size = d.desired_box.size
var new_size = lerp(old_size, desired_size, delta * 30 * Util.animation_speed)
#if old_size.length_squared() > desired_size.length_squared():
#new_size = lerp(old_size, desired_size, delta * 30 * animation_speed)
#else:
#new_size = lerp(old_size, desired_size, delta * 30 * animation_speed)
var old_center = d.box.get_center()
var desired_center = d.desired_box.get_center()
var new_center = lerp(old_center, desired_center, delta * 50 * Util.animation_speed)
d.box = Rect2(new_center - new_size / 2.0, new_size)
d.opacity = lerp(d.opacity, d.desired_opacity, delta * 20 * Util.animation_speed)
func _update_display_animation_exploding(d: Cursor, delta):
var old_size = d.box.size
var desired_size = d.desired_box.size
var new_size = lerp(old_size, desired_size, delta * 20 * Util.animation_speed)
var old_center = d.box.get_center()
var desired_center = d.desired_box.get_center()
var new_center = lerp(old_center, desired_center, delta * 50 * Util.animation_speed)
d.box = Rect2(new_center - new_size / 2.0, new_size)
d.opacity = lerp(d.opacity, d.desired_opacity, delta * 15 * Util.animation_speed)
func _update_display_animation_fading(d: Cursor, delta):
var current_top = min(d.box.position.y, d.box.position.y + d.box.size.y)
var current_bottom = max(d.box.position.y, d.box.position.y + d.box.size.y)
var current_left = min(d.box.position.x, d.box.position.x + d.box.size.x)
var current_right = max(d.box.position.x, d.box.position.x + d.box.size.x)
var desired_top = min(d.desired_box.position.y, d.desired_box.position.y + d.desired_box.size.y)
var desired_bottom = max(d.desired_box.position.y, d.desired_box.position.y + d.desired_box.size.y)
var desired_left = min(d.desired_box.position.x, d.desired_box.position.x + d.desired_box.size.x)
var desired_right = max(d.desired_box.position.x, d.desired_box.position.x + d.desired_box.size.x)
var new_top = lerp(current_top, desired_top, delta * Util.animation_speed * 40)
var new_bottom = lerp(current_bottom, desired_bottom, delta * Util.animation_speed * 40)
var new_left = lerp(current_left, desired_left, delta * Util.animation_speed * 40)
var new_right = lerp(current_right, desired_right, delta * Util.animation_speed * 40)
d.box = Rect2(
new_left,
new_top,
new_right - new_left,
new_bottom - new_top
)
d.opacity = lerp(d.opacity, d.desired_opacity, delta * 10 * Util.animation_speed)
func _update_display_animation_area(d: Cursor, delta):
var current_top = min(d.box.position.y, d.box.position.y + d.box.size.y)
var current_bottom = max(d.box.position.y, d.box.position.y + d.box.size.y)
var current_left = min(d.box.position.x, d.box.position.x + d.box.size.x)
var current_right = max(d.box.position.x, d.box.position.x + d.box.size.x)
var desired_top = min(d.desired_box.position.y, d.desired_box.position.y + d.desired_box.size.y)
var desired_bottom = max(d.desired_box.position.y, d.desired_box.position.y + d.desired_box.size.y)
var desired_left = min(d.desired_box.position.x, d.desired_box.position.x + d.desired_box.size.x)
var desired_right = max(d.desired_box.position.x, d.desired_box.position.x + d.desired_box.size.x)
var new_top = lerp(current_top, desired_top, delta * Util.animation_speed * 40)
var new_bottom = lerp(current_bottom, desired_bottom, delta * Util.animation_speed * 40)
var new_left = lerp(current_left, desired_left, delta * Util.animation_speed * 40)
var new_right = lerp(current_right, desired_right, delta * Util.animation_speed * 40)
d.box = Rect2(
new_left,
new_top,
new_right - new_left,
new_bottom - new_top
)
d.opacity = lerp(d.opacity, d.desired_opacity, delta * 20 * Util.animation_speed)