181 lines
4.9 KiB
GDScript
181 lines
4.9 KiB
GDScript
extends KinematicBody2D
|
|
|
|
|
|
signal died()
|
|
signal health_changed(amount)
|
|
signal energy_changed(amount,laser_energy)
|
|
|
|
|
|
enum State {DEAD, STAND, FORWARD, BACK, DUCK, BEAM, INACTIVE}
|
|
|
|
const Bullet = preload("res://objects/enemy/2083_bullet.tscn")
|
|
const SmallExplosion = preload("res://objects/enemy/boss/2600_small_explosion.tscn")
|
|
|
|
|
|
export var hp: float = 100.0
|
|
export var max_energy: float = 100.0
|
|
export var energy_recovery: float = 5.0
|
|
export var shot_speed: float = 50.0
|
|
export var move_speed: float = 30.0
|
|
export var safe_from_breath: bool = false
|
|
export var make_explosions: bool = false
|
|
export var bullet_damage: float = 0.2
|
|
export var bullet_energy: float = 0.0
|
|
export var beam_energy: float = 75.0
|
|
export var duck_energy: float = 0.15
|
|
export var explosion_rect: Rect2
|
|
export var famira_path: NodePath
|
|
|
|
|
|
var state: int = State.STAND
|
|
var knockback: float = 0.0
|
|
var energy: float = max_energy
|
|
|
|
|
|
onready var bullet_positions = $"%BulletPositions"
|
|
onready var anims: AnimationPlayer = $"%AnimationPlayer"
|
|
onready var head_sprite = $"%Head"
|
|
|
|
|
|
func _physics_process(delta: float) -> void:
|
|
match state:
|
|
State.DEAD:
|
|
return
|
|
State.INACTIVE:
|
|
return
|
|
State.STAND:
|
|
if sign(Input.get_axis("move_up", "move_down") + get_stick_input(JOY_AXIS_1)) == 1 and energy >= duck_energy:
|
|
state = State.DUCK
|
|
anims.play("Duck")
|
|
elif Input.is_action_pressed("move_right"):
|
|
state = State.FORWARD
|
|
anims.play("Walk")
|
|
elif Input.is_action_pressed("move_left"):
|
|
state = State.BACK
|
|
anims.play("Walk", -1.0, -1.0, true)
|
|
State.DUCK:
|
|
if (!Input.is_action_pressed("move_down") && get_stick_input(JOY_AXIS_1) != 1) and anims.current_animation.empty():
|
|
anims.play("UnDuck")
|
|
energy -= duck_energy
|
|
|
|
State.FORWARD:
|
|
move_and_slide(Vector2(move_speed, 0.0))
|
|
State.BACK:
|
|
move_and_slide(Vector2(-move_speed, 0.0))
|
|
move_and_slide(Vector2(-knockback, 0.0))
|
|
knockback *= pow(0.1, delta)
|
|
set_energy(energy + energy_recovery * delta)
|
|
|
|
|
|
func _input(event: InputEvent) -> void:
|
|
if state == State.DEAD or state == State.INACTIVE:
|
|
return
|
|
if event.is_action_pressed("shoot") and (state == State.STAND or state == State.FORWARD or state == State.BACK) and energy >= bullet_energy:
|
|
shoot()
|
|
if event.is_action_pressed("jump") and state == State.STAND and energy >= beam_energy:
|
|
beam()
|
|
|
|
func get_stick_input(axis):
|
|
var inp = Input.get_joy_axis(0,axis)
|
|
if abs(inp) >= 0.5:
|
|
return sign(inp)
|
|
else:
|
|
return 0
|
|
|
|
func set_energy(value: float) -> void:
|
|
energy = clamp(value, 0.0, max_energy)
|
|
emit_signal("energy_changed", energy, beam_energy)
|
|
|
|
func land(duck: bool) -> void:
|
|
if duck:
|
|
anims.play("Duck")
|
|
else:
|
|
anims.play("UnDuck")
|
|
|
|
|
|
func shoot() -> void:
|
|
set_energy(energy - bullet_energy)
|
|
Audio.play_sound(Audio.a_vulcan,Audio.ac_menu)
|
|
for pos in bullet_positions.get_children():
|
|
var bullet = Bullet.instance()
|
|
bullet.global_position = pos.global_position
|
|
bullet.direction = Vector2.LEFT.rotated(pos.rotation)
|
|
bullet.speed = shot_speed
|
|
bullet.damage = bullet_damage
|
|
get_parent().add_child(bullet)
|
|
|
|
|
|
func beam() -> void:
|
|
state = State.BEAM
|
|
var tween = create_tween()
|
|
tween.tween_method(self, "set_energy", energy, energy - beam_energy, 0.9)
|
|
anims.play("Beam")
|
|
|
|
|
|
func hurt(amount: float, can_duck: bool = false) -> void:
|
|
if can_duck and state == State.DUCK:
|
|
return
|
|
hp -= amount
|
|
emit_signal("health_changed", hp)
|
|
if state != State.DEAD and hp <= 0.0:
|
|
state = State.DEAD
|
|
emit_signal("died")
|
|
anims.play("die")
|
|
|
|
|
|
func knock_back(amount: float, can_duck: bool = false) -> void:
|
|
if can_duck and state == State.DUCK:
|
|
return
|
|
knockback += amount
|
|
print("YOWCH")
|
|
|
|
|
|
func _play_laser_sound(play: bool):
|
|
var famira = get_node(famira_path)
|
|
if play:
|
|
if famira.has_method("start_push"):
|
|
famira.start_push()
|
|
Audio.play_sound(Audio.a_rainbow_laser,Audio.ac_collectible)
|
|
else:
|
|
if famira.has_method("stop_push"):
|
|
famira.stop_push()
|
|
Audio.ac_collectible.playing = false
|
|
|
|
|
|
func _play_charge_sound(play: bool):
|
|
if play:
|
|
Audio.play_sound(Audio.a_2600_charge,Audio.ac_collectible)
|
|
else:
|
|
Audio.ac_collectible.playing = false
|
|
|
|
|
|
func _spawn_explosions() -> void:
|
|
while make_explosions:
|
|
yield(get_tree().create_timer(randf() * 0.5, false), "timeout")
|
|
var explosion = SmallExplosion.instance()
|
|
explosion.position = Vector2(
|
|
rand_range(explosion_rect.position.x, explosion_rect.end.x),
|
|
rand_range(explosion_rect.position.y, explosion_rect.end.y)
|
|
)
|
|
add_child(explosion)
|
|
|
|
|
|
func _on_animation_finished(anim_name: String) -> void:
|
|
if state == State.INACTIVE:
|
|
return
|
|
match anim_name:
|
|
"UnDuck":
|
|
state = State.STAND
|
|
"Walk":
|
|
if state == State.FORWARD and Input.is_action_pressed("move_right"):
|
|
anims.play("Walk")
|
|
elif state == State.BACK and Input.is_action_pressed("move_left"):
|
|
anims.play("Walk", -1.0, -1.0, true)
|
|
else:
|
|
state = State.STAND
|
|
"Beam":
|
|
state = State.STAND
|
|
"die":
|
|
var map = Game.get_map()
|
|
var gover = load("res://menus/game_over.tscn").instance()
|
|
map.add_child(gover)
|