forked from team-sg/hero-mark-2
108 lines
3.5 KiB
GDScript
108 lines
3.5 KiB
GDScript
tool
|
|
extends "res://objects/enemy/enemy_move_sidesideupdown.gd"
|
|
|
|
## positions along the path where spikes will trigger
|
|
export (Array, float) var spike_positions: Array = []
|
|
## time spikes stay active
|
|
export var spike_time: float = 0.25
|
|
|
|
# animates the spikes
|
|
var can_spike: bool = true
|
|
var spike_tween: SceneTreeTween
|
|
|
|
# index of the current spike position to check for
|
|
onready var current_spike_position: int = 0
|
|
onready var sprite: Sprite = $"%Sprite"
|
|
onready var spike_shape: CollisionShape2D = $"%SpikeShape"
|
|
|
|
func _ready() -> void:
|
|
# don't act in the editor
|
|
if Engine.editor_hint:
|
|
return
|
|
|
|
# positions must be in order
|
|
spike_positions.sort()
|
|
for i in spike_positions.size():
|
|
# scale to be in tiles
|
|
spike_positions[i] = spike_positions[i] * 8.0
|
|
# should start with the first positive spike position
|
|
if spike_positions[i] < 0.0:
|
|
current_spike_position = i + 1
|
|
|
|
func _process(delta: float) -> void:
|
|
# update debug graphics in editor
|
|
if Engine.editor_hint and Engine.get_frames_drawn() % 10 == 0:
|
|
update()
|
|
|
|
func _physics_process(delta: float) -> void:
|
|
# do nothing in editor
|
|
if Engine.editor_hint:
|
|
return
|
|
|
|
# sync hitbox
|
|
$HeadHitbox.scale.x = $ToFlip.scale.x
|
|
|
|
# check if can still spike before doing all this work
|
|
if not can_spike:
|
|
return
|
|
# use positions in correct axis
|
|
var pos = position.x if move_direction == Direction.HORIZONTAL else position.y
|
|
var pos_start = startpos.x if move_direction == Direction.HORIZONTAL else startpos.y
|
|
# slightly different logic depending on forward/backwards unfortunately :I
|
|
match sign(direction):
|
|
1.0:
|
|
# make sure there are any positions left to check in this direction
|
|
if current_spike_position < spike_positions.size():
|
|
# check if passed the spike position
|
|
if pos >= pos_start + spike_positions[current_spike_position]:
|
|
# move on to next position
|
|
current_spike_position += 1
|
|
spike()
|
|
-1.0:
|
|
# make sure there are still positions left in this direction
|
|
if current_spike_position - 1 >= 0:
|
|
# check if passed the position
|
|
if pos <= pos_start + spike_positions[current_spike_position - 1]:
|
|
# move on to next (previous because backwards) position
|
|
current_spike_position -= 1
|
|
spike()
|
|
|
|
## performs the spike animation
|
|
func spike() -> void:
|
|
# reset tween
|
|
if spike_tween != null:
|
|
spike_tween.kill() # never have two tweens acting on the same thing
|
|
spike_tween = create_tween()
|
|
spike_tween.set_process_mode(Tween.TWEEN_PROCESS_PHYSICS)
|
|
# indicator sprite
|
|
spike_tween.tween_property(sprite, "frame_coords:y", 1.0, 0.0)
|
|
spike_tween.tween_interval(spike_time * 2.0)
|
|
# spikes active
|
|
spike_tween.tween_property(spike_shape, "disabled", false, 0.0)
|
|
spike_tween.tween_property(sprite, "frame_coords:y", 2.0, 0.0)
|
|
spike_tween.tween_interval(spike_time)
|
|
# spikes gone once more
|
|
spike_tween.tween_property(spike_shape, "disabled", true, 0.0)
|
|
spike_tween.tween_property(sprite, "frame_coords:y", 0.0, 0.0)
|
|
|
|
func die() -> void:
|
|
# disable spiking
|
|
can_spike = false
|
|
# stop tween
|
|
if spike_tween != null:
|
|
spike_tween.kill()
|
|
# disable hitbox
|
|
spike_shape.set_deferred("disabled", true)
|
|
# reset animation
|
|
sprite.frame_coords.y = 3
|
|
Audio.play_sound(death_sound, Audio.ac_die)
|
|
$"%DeathSplatter".emitting = true
|
|
|
|
func _draw() -> void:
|
|
if Engine.editor_hint:
|
|
# still draw base moving enemy debug lines
|
|
._draw()
|
|
# draw dots at spike positions
|
|
for pos in spike_positions:
|
|
var dir = Vector2.RIGHT if move_direction == Direction.HORIZONTAL else Vector2.DOWN
|
|
draw_circle(dir * pos * 8.0, 2.0, Color.red)
|