126 lines
3.4 KiB
GDScript
126 lines
3.4 KiB
GDScript
extends Node
|
|
|
|
const TRAIL_GHOSTS := 8
|
|
const TRAIL_SPACING := 3.0
|
|
const TRAIL_ALPHAS := [0.5, 0.42, 0.34, 0.27, 0.2, 0.14, 0.09, 0.05]
|
|
const GLOW_PADDING := Vector2(6, 6)
|
|
const GLOW_COLOR := Color(1, 0.3, 0.3, 0.35)
|
|
|
|
var pulse_speed := 80.0
|
|
var pulse_speed_initial := 80.0
|
|
var pulse_speed_per_floor := 8.0
|
|
var pulse_speed_increase := 15.0
|
|
var pulse_x := 0.0
|
|
var pulse_active := false
|
|
var pulse_gap := 1.0
|
|
var pulse_gap_decrease := 0.05
|
|
var pulse_gap_min := 0.3
|
|
var pulses_blocked := 0
|
|
|
|
var _sweep_line: ColorRect
|
|
var _target_zone: ColorRect
|
|
var _perfect_zone: ColorRect
|
|
var _screen_width: float
|
|
var _glow: ColorRect
|
|
var _trail: Array[ColorRect] = []
|
|
|
|
signal pulse_started(duration: float)
|
|
signal pulse_blocked
|
|
signal pulse_blocked_perfect
|
|
signal pulse_escaped
|
|
|
|
func configure(sweep_line: ColorRect, target_zone: ColorRect, perfect_zone: ColorRect, screen_width: float):
|
|
_sweep_line = sweep_line
|
|
_target_zone = target_zone
|
|
_perfect_zone = perfect_zone
|
|
_screen_width = screen_width
|
|
_build_visuals()
|
|
|
|
func _build_visuals():
|
|
var host: Control = _sweep_line.get_parent() as Control
|
|
_glow = ColorRect.new()
|
|
_glow.color = GLOW_COLOR
|
|
_glow.size = Vector2(_sweep_line.size.x + GLOW_PADDING.x * 2, _sweep_line.size.y + GLOW_PADDING.y * 2)
|
|
_glow.visible = false
|
|
host.add_child(_glow)
|
|
host.move_child(_glow, 0)
|
|
|
|
for i in TRAIL_GHOSTS:
|
|
var ghost := ColorRect.new()
|
|
ghost.color = Color(_sweep_line.color.r, _sweep_line.color.g, _sweep_line.color.b, TRAIL_ALPHAS[i])
|
|
ghost.size = _sweep_line.size
|
|
ghost.visible = false
|
|
host.add_child(ghost)
|
|
host.move_child(ghost, 0)
|
|
_trail.append(ghost)
|
|
|
|
func start_floor(floor_num: int):
|
|
pulses_blocked = 0
|
|
var floors_descended = EventBus.STARTING_FLOOR - floor_num
|
|
pulse_speed = pulse_speed_initial + floors_descended * pulse_speed_per_floor
|
|
pulse_gap = 1.0
|
|
pulse_active = false
|
|
|
|
func launch():
|
|
pulse_x = 0.0
|
|
pulse_active = true
|
|
_sweep_line.visible = true
|
|
_sweep_line.position.x = 0
|
|
_glow.visible = true
|
|
for ghost in _trail:
|
|
ghost.visible = true
|
|
pulse_started.emit(_screen_width / pulse_speed)
|
|
|
|
func attempt_block() -> bool:
|
|
if not pulse_active:
|
|
return false
|
|
var bz_left = _target_zone.position.x
|
|
var bz_right = _target_zone.position.x + _target_zone.size.x
|
|
if pulse_x >= bz_left and pulse_x <= bz_right:
|
|
var perfect_left = bz_left + _perfect_zone.position.x
|
|
var perfect_right = perfect_left + _perfect_zone.size.x
|
|
var was_perfect = pulse_x >= perfect_left and pulse_x <= perfect_right
|
|
pulse_active = false
|
|
pulses_blocked += 1
|
|
pulse_speed += pulse_speed_increase
|
|
pulse_gap = max(pulse_gap - pulse_gap_decrease, pulse_gap_min)
|
|
_hide_visuals()
|
|
pulse_blocked.emit()
|
|
if was_perfect:
|
|
pulse_blocked_perfect.emit()
|
|
return true
|
|
else:
|
|
pulse_active = false
|
|
_hide_visuals()
|
|
pulse_escaped.emit()
|
|
return false
|
|
|
|
func get_pulse_gap() -> float:
|
|
return pulse_gap
|
|
|
|
func stop():
|
|
pulse_active = false
|
|
_hide_visuals()
|
|
|
|
func _process(delta):
|
|
if not pulse_active:
|
|
return
|
|
pulse_x += pulse_speed * delta
|
|
_sweep_line.position.x = pulse_x
|
|
_glow.position = Vector2(pulse_x - GLOW_PADDING.x, _sweep_line.position.y - GLOW_PADDING.y)
|
|
for i in _trail.size():
|
|
var gx = pulse_x - (i + 1) * TRAIL_SPACING
|
|
_trail[i].visible = gx >= 0
|
|
_trail[i].position = Vector2(gx, _sweep_line.position.y)
|
|
if pulse_x >= _screen_width:
|
|
pulse_active = false
|
|
_hide_visuals()
|
|
pulse_escaped.emit()
|
|
|
|
func _hide_visuals():
|
|
if _sweep_line:
|
|
_sweep_line.visible = false
|
|
if _glow:
|
|
_glow.visible = false
|
|
for ghost in _trail:
|
|
ghost.visible = false
|