112 lines
2.5 KiB
GDScript3
112 lines
2.5 KiB
GDScript3
|
extends Control
|
||
|
|
||
|
signal solved
|
||
|
signal input(correct: bool)
|
||
|
|
||
|
var InputHandler := preload('res://game/input.gd')
|
||
|
|
||
|
const all_data := preload('res://game/gems/data.gd').data
|
||
|
const ArrowScene := preload('res://game/arrow/arrow.tscn')
|
||
|
const total_width := 1920
|
||
|
const space_between_arrows := 8
|
||
|
const img_size := 48
|
||
|
|
||
|
@onready var icons := $Icons
|
||
|
@onready var name_label := $Name
|
||
|
@onready var arrows_container := $Arrows
|
||
|
@onready var error_timer := $ErrorTimer
|
||
|
@onready var player := $AnimationPlayer
|
||
|
|
||
|
var pos := -1
|
||
|
var arrow_count := 0
|
||
|
var raw_dirs: Array[Global.DIRS] = []
|
||
|
var arrows: Array[Arrow] = []
|
||
|
var in_error := true
|
||
|
var next_codes = []
|
||
|
|
||
|
func _on_error_timer_timeout() -> void:
|
||
|
in_error = false
|
||
|
|
||
|
func dir_input(dir: Global.DIRS) -> void:
|
||
|
if in_error:
|
||
|
return
|
||
|
|
||
|
if pos >= len(raw_dirs):
|
||
|
return
|
||
|
|
||
|
if dir == raw_dirs[pos]:
|
||
|
arrows[pos].state = Global.ARROW_STATE.DONE
|
||
|
pos += 1
|
||
|
if pos == arrow_count:
|
||
|
solved.emit()
|
||
|
start_new_round()
|
||
|
input.emit(true)
|
||
|
else:
|
||
|
in_error = true
|
||
|
error_timer.start()
|
||
|
arrows[pos].state = Global.ARROW_STATE.ERROR
|
||
|
for a in arrows:
|
||
|
a.state = Global.ARROW_STATE.NORMAL
|
||
|
pos = 0
|
||
|
input.emit(false)
|
||
|
|
||
|
|
||
|
func start_new_round() -> void:
|
||
|
InputHandler.start = null
|
||
|
var data = next_codes.pop_front()
|
||
|
next_codes.append(all_data[randi() % all_data.size()])
|
||
|
|
||
|
icons.update(data[1], next_codes)
|
||
|
|
||
|
in_error = true
|
||
|
|
||
|
if pos != -1:
|
||
|
raw_dirs.clear()
|
||
|
|
||
|
player.play('round-end')
|
||
|
await player.animation_finished
|
||
|
|
||
|
for n in arrows:
|
||
|
arrows_container.remove_child(n)
|
||
|
n.queue_free()
|
||
|
|
||
|
arrows.clear()
|
||
|
|
||
|
pos = 0
|
||
|
name_label.text = data[0]
|
||
|
raw_dirs.append_array(data[2])
|
||
|
|
||
|
arrow_count = len(data[2])
|
||
|
var total_arrow_width := 64 * arrow_count + space_between_arrows * (arrow_count - 1)
|
||
|
var start_x := (total_width - total_arrow_width) / 2.0
|
||
|
for d in data[2]:
|
||
|
var a: Arrow = ArrowScene.instantiate()
|
||
|
a.set_position(Vector2(start_x, 500))
|
||
|
a.dir = d
|
||
|
arrows.append(a)
|
||
|
arrows_container.add_child(a)
|
||
|
start_x += 64 + space_between_arrows
|
||
|
|
||
|
player.play('round-start')
|
||
|
await player.animation_finished
|
||
|
|
||
|
in_error = false
|
||
|
|
||
|
|
||
|
func _input(event: InputEvent) -> void:
|
||
|
var d = InputHandler._input(event)
|
||
|
if d != null:
|
||
|
dir_input(d)
|
||
|
|
||
|
if event.is_action_released('escape'):
|
||
|
get_tree().change_scene_to_packed(load('res://main_menu/main_menu.tscn'))
|
||
|
|
||
|
func _ready() -> void:
|
||
|
randomize()
|
||
|
for i in range(8):
|
||
|
next_codes.append(all_data[randi() % all_data.size()])
|
||
|
icons.update(null, next_codes)
|
||
|
start_new_round()
|
||
|
solved.connect($StatContainer/Solved._on_solved)
|
||
|
input.connect($StatContainer/Combo._on_input)
|