revo-jailbreak/objects/enemy/turtle.gd

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)