forked from team-sg/hero-mark-2
113 lines
3.7 KiB
GDScript
113 lines
3.7 KiB
GDScript
tool
|
|
extends "res://objects/enemy/enemy_move_sidesideupdown.gd"
|
|
|
|
enum SpikeDirection {BOTH, LEFT, RIGHT}
|
|
|
|
## 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
|
|
## which direction the turtle should be able to spike
|
|
export (SpikeDirection) var spike_direction: int = SpikeDirection.BOTH
|
|
|
|
# animates the spikes
|
|
var can_spike: bool = true
|
|
var spike_tween: SceneTreeTween
|
|
|
|
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
|
|
|
|
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
|
|
# only spike if matching direction
|
|
if spike_direction == SpikeDirection.LEFT and sign(direction) == 1.0:
|
|
return
|
|
if spike_direction == SpikeDirection.RIGHT and sign(direction) == -1.0:
|
|
return
|
|
# spike if close enough to an activation point
|
|
for spike_pos in spike_positions:
|
|
if abs(pos_start + (spike_pos * 8.0) - pos) <= 2.0:
|
|
spike()
|
|
break
|
|
# 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
|
|
# if spike_direction != SpikeDirection.LEFT:
|
|
# 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
|
|
# if spike_direction != SpikeDirection.RIGHT:
|
|
# 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)
|