104 lines
3.1 KiB
GDScript
104 lines
3.1 KiB
GDScript
extends "res://objects/enemy/enemy.gd"
|
|
|
|
enum State {SWIMMING, FALLING, TRANSITION}
|
|
|
|
# whether the squid should start in falling state
|
|
export var start_falling: bool = false
|
|
export var speed: float = 50.0
|
|
export var damping: float = 0.9
|
|
export var delay: float = 1.0
|
|
# margin of screen hitbox is disabled in
|
|
export var hitbox_clip: Rect2 = Rect2(0.0, 0.0, 7.0, 7.0)
|
|
export var full_clip: Rect2 = Rect2(-4.0, -4.0, 16.0, 16.0)
|
|
|
|
|
|
var velocity: Vector2 = Vector2.ZERO
|
|
# start of the sector it is trapped in
|
|
var home_sector: Vector2 = Vector2.ZERO
|
|
var _can_transition: bool = true
|
|
|
|
|
|
onready var current_state: int = State.SWIMMING
|
|
onready var hitbox_shape: CollisionShape2D = $"%HitboxShape"
|
|
onready var animation_player: AnimationPlayer = $AnimationPlayer
|
|
|
|
|
|
func _ready() -> void:
|
|
if start_falling:
|
|
_start_falling()
|
|
else:
|
|
_start_swimming()
|
|
home_sector = Game.get_sector(global_position)
|
|
|
|
func _physics_process(delta: float) -> void:
|
|
if Game.current_sector != home_sector:
|
|
hitbox_shape.disabled = true
|
|
return
|
|
# process movement and apply damping
|
|
velocity.y *= pow(damping, delta)
|
|
if current_state == State.FALLING:
|
|
velocity.y = speed
|
|
global_position += velocity * delta
|
|
|
|
var sector_rect = Rect2(home_sector * Game.resolution, Game.resolution)
|
|
|
|
# disable hitbox at edge of screen
|
|
var global_hitbox_clip = hitbox_clip
|
|
global_hitbox_clip.position += global_position
|
|
if sector_rect.encloses(global_hitbox_clip):
|
|
hitbox_shape.disabled = false
|
|
else:
|
|
hitbox_shape.disabled = true
|
|
|
|
# check if out of sector
|
|
var global_full_clip = full_clip
|
|
global_full_clip.position += global_position
|
|
if not sector_rect.intersects(global_full_clip) and _can_transition:
|
|
match current_state:
|
|
State.SWIMMING:
|
|
current_state = State.TRANSITION
|
|
_can_transition = false
|
|
velocity = Vector2.ZERO
|
|
var tween = create_tween()
|
|
tween.tween_interval(delay)
|
|
tween.tween_callback(self, "_start_falling")
|
|
State.FALLING:
|
|
current_state = State.TRANSITION
|
|
_can_transition = false
|
|
velocity = Vector2.ZERO
|
|
var tween = create_tween()
|
|
tween.tween_interval(delay)
|
|
tween.tween_callback(self, "_start_swimming")
|
|
State.TRANSITION:
|
|
pass
|
|
|
|
# clip to inside of home sector
|
|
var rid = get_canvas_item()
|
|
var rect = Rect2(to_local(home_sector * Game.resolution), Game.resolution)
|
|
VisualServer.canvas_item_set_custom_rect(rid, true, rect)
|
|
VisualServer.canvas_item_set_clip(rid, true)
|
|
|
|
|
|
# give a burst of speed
|
|
func _propel() -> void:
|
|
velocity.y = -speed
|
|
|
|
func _start_falling() -> void:
|
|
if not _can_transition:
|
|
var player = get_tree().get_nodes_in_group("player").pop_back()
|
|
if player != null:
|
|
global_position.x = player.global_position.x - 3.0
|
|
animation_player.play("falling")
|
|
current_state = State.FALLING
|
|
yield(create_tween().tween_interval(1.0), "finished")
|
|
_can_transition = true
|
|
|
|
func _start_swimming() -> void:
|
|
if not _can_transition:
|
|
var player = get_tree().get_nodes_in_group("player").pop_back()
|
|
if player != null:
|
|
global_position.x = player.global_position.x - 3.0
|
|
animation_player.play("swimming")
|
|
current_state = State.SWIMMING
|
|
yield(create_tween().tween_interval(1.0), "finished")
|
|
_can_transition = true
|