class_name Launcher extends Node2D signal get_firing signal is_full signal gain_new_bullet signal interrupt_wave signal move_visor enum State { READY, FIRING, WAITING, INTERRUPTING, DEAD } const visor_min_heigth = 10 const visor_start_shift = Vector2(0, -visor_min_heigth) const Ball = preload("res://component/entity/ball/Ball.tscn") export (float) var bullet_speed = 500.0 export (float) var visor_ratio = 1.0 var nbAmmo := 0 var nbStorage := 1 var current_state = State.WAITING onready var target = $TargetLine onready var visor = $TargetLine/TargetVisor onready var source = $Source onready var shootDelay = $ShootDelay func _ready() -> void: get_ready() func _input(event: InputEvent) -> void: if event is InputEventMouseButton and event.is_pressed(): trigger(event.position) elif event is InputEventMouseMotion and current_state == State.READY: aim_at(event.position) func aim_at(cursor: Vector2) -> void: var visor_pos = (cursor - source.position) * visor_ratio if abs(visor_pos.y) > visor_min_heigth: visor.position = visor_pos emit_signal("move_visor") func trigger(aim: Vector2) -> void: if (current_state == State.READY): current_state = State.FIRING emit_signal("get_firing") elif (current_state == State.WAITING): current_state = State.INTERRUPTING emit_signal("interrupt_wave") func shoot() -> void: var bullet = Ball.instance() bullet.position = source.position bullet.linear_velocity = (target.get_visor_pos() - source.position).normalized() bullet.linear_velocity *= bullet_speed add_child(bullet) bullet.connect("tree_exited", self, "_on_Ball_tree_exited") self.connect("interrupt_wave", bullet, "_on_Launcher_interrupt_wave") func gain_new_bullet() -> void: load_bullet(1) emit_signal("gain_new_bullet") func load_bullet(n: int) -> void: nbStorage += n func end_of_round() -> void: if (current_state != State.DEAD): get_ready() func get_ready() -> void: current_state = State.READY target.set_visor_pos(source.position + visor_start_shift) nbAmmo = nbStorage nbStorage = 0 func die() -> void: current_state = State.DEAD func _on_ShootDelay_timeout() -> void: shoot() nbAmmo -= 1 if (nbAmmo <= 0): current_state = State.WAITING else: emit_signal("get_firing") func _on_Launcher_get_firing() -> void: shootDelay.start() func _on_Ball_tree_exited() -> void: if get_tree() == null: return # Game is exiting load_bullet(1) if (get_tree().get_nodes_in_group("ball").size() == 0): emit_signal("is_full") func _on_Grid_has_moved() -> void: end_of_round() func _on_Grid_kace_broken() -> void: gain_new_bullet() func _on_DeadLine_game_lost() -> void: die()