112 lines
2.4 KiB
GDScript
112 lines
2.4 KiB
GDScript
extends CharacterBody3D
|
|
|
|
const SPEED = 2.5
|
|
const JUMP_VELOCITY = 4.5
|
|
|
|
var face_rotation = null
|
|
var face_left = false
|
|
|
|
var health = 35
|
|
var mid_knockback = false
|
|
|
|
@onready var player = get_parent().get_node("Player")
|
|
|
|
enum {
|
|
STATE_IDLE,
|
|
STATE_JUMP,
|
|
STATE_LEAP,
|
|
STATE_HIT,
|
|
STATE_DEATH
|
|
}
|
|
|
|
var state = STATE_IDLE
|
|
var state_timer = 1
|
|
|
|
var iframes = 0
|
|
|
|
@onready var game = get_parent()
|
|
@onready var camera = game.get_node("PlayerCamera")
|
|
|
|
func on_knockback() -> void:
|
|
state_timer = 99999
|
|
state = STATE_HIT
|
|
$Body/Animator.play("leap")
|
|
|
|
func _ready() -> void:
|
|
$Body.look_at(game.get_node("PlayerCamera").global_position)
|
|
$Body.rotation.x = 0
|
|
face_rotation = $Body.rotation.y
|
|
|
|
$Body/Animator.play("idle")
|
|
|
|
func _physics_process(delta: float) -> void:
|
|
if (health <= 0) and (state != STATE_DEATH):
|
|
state = STATE_DEATH
|
|
state_timer = 0.75
|
|
$Body/Animator.play("jump")
|
|
|
|
state_timer -= delta
|
|
|
|
if state_timer < 0:
|
|
if state == STATE_IDLE:
|
|
state = STATE_JUMP
|
|
state_timer = 0.6
|
|
$Body/Animator.play("jump")
|
|
|
|
elif state == STATE_JUMP:
|
|
state = STATE_LEAP
|
|
state_timer = 99999
|
|
$Body/Animator.play("leap")
|
|
velocity = global_position.direction_to(player.global_position) * 3
|
|
velocity.y = 3
|
|
|
|
elif state == STATE_DEATH:
|
|
queue_free()
|
|
|
|
elif (state == STATE_LEAP) and is_on_floor():
|
|
state = STATE_IDLE
|
|
state_timer = randf_range(0.8, 1.5)
|
|
|
|
$Body/Animator.play("idle")
|
|
elif (state == STATE_HIT) and is_on_floor():
|
|
state = STATE_IDLE
|
|
state_timer = 0.5
|
|
|
|
$Body/Animator.play("idle")
|
|
elif (state == STATE_DEATH):
|
|
pass
|
|
|
|
if iframes > 0:
|
|
iframes -= delta
|
|
$Body.modulate.a = 0.5
|
|
else:
|
|
$Body.modulate.a = 1
|
|
|
|
#wa$HealthLabel.text = str(health)
|
|
|
|
if not is_on_floor():
|
|
velocity += get_gravity() * delta
|
|
|
|
var viewport_half = (get_viewport().get_visible_rect().size / 2.0)
|
|
var player_position = camera.unproject_position(global_transform.origin)
|
|
|
|
if face_left:
|
|
$Body.rotation.y = face_rotation + deg_to_rad(180)
|
|
else:
|
|
$Body.rotation.y = face_rotation
|
|
|
|
if is_on_floor() and not mid_knockback:
|
|
velocity.x = move_toward(velocity.x, 0, delta * 16)
|
|
velocity.z = move_toward(velocity.z, 0, delta * 16)
|
|
|
|
move_and_slide()
|
|
|
|
if player in $HitCollision.get_overlapping_bodies():
|
|
if player.iframes <= 0:
|
|
player.health -= 20
|
|
player.on_hit(self)
|
|
|
|
if mid_knockback: mid_knockback = false
|
|
|
|
$Shadow.global_position.y = $Floorcast.get_collision_point().y + 0.01
|
|
|