Files
Kalulu/sources/minigames/jellyfish/jellyfish_minigame.gd
T
2026-01-14 14:49:25 +01:00

186 lines
5.5 KiB
GDScript

extends SyllablesMinigame
const JELLYFISH_SCENE: PackedScene = preload("res://sources/minigames/jellyfish/jellyfish.tscn")
var difficulty_settings: Array[DifficultySettings] = [
DifficultySettings.new(4, 0.75, 150),
DifficultySettings.new(3, 0.66, 175),
DifficultySettings.new(2, 0.33, 200),
DifficultySettings.new(1, 0.25, 250),
DifficultySettings.new(1, 0.25, 300)
]
var blocking_jellyfish: Array[Jellyfish] = []
@onready var spawning_space: Control = %SpawningSpace
@onready var spawn_timer: Timer = $GameRoot/SpawnTimer
func _start() -> void:
super()
fireworks.set_colors([Color("#ffd366"), Color("#ffbf94"), Color("#f5a8c8")])
spawn_timer.start()
func _process(delta: float) -> void:
for jellyfish: Jellyfish in spawning_space.get_children():
# Moves the jellyfish upward
if jellyfish.is_idle():
jellyfish.position.y -= _get_difficulty_settings().velocity * delta
# Handles the blocking array
if jellyfish in blocking_jellyfish and jellyfish.position.y + jellyfish.size.y < spawning_space.size.y:
blocking_jellyfish.erase(jellyfish)
# Destroy the jellyfish when it leaves the screen
if jellyfish.position.y + jellyfish.size.y < 0:
jellyfish.queue_free()
func _highlight() -> void:
for jellyfish: Jellyfish in spawning_space.get_children():
if jellyfish.stimulus and _is_stimulus_right(jellyfish.stimulus):
jellyfish.highlight()
func _stop_highlight() -> void:
for jellyfish: Jellyfish in spawning_space.get_children():
jellyfish.stop_highlight()
func _spawn() -> void:
# Instantiate a new jellyfish
var new_jellyfish: Jellyfish = JELLYFISH_SCENE.instantiate()
spawning_space.add_child(new_jellyfish)
# Find the right size for the jellyfish
var jellyfish_width: float = new_jellyfish.size.x * new_jellyfish.scale.x
# Check if there is enough space to spawn the jellyfish and find a spot
var permitted_range: float = 0.
var left_border: float = 0.
# Blocking jellyfish is supposed to be ordered
for blocking: Jellyfish in blocking_jellyfish:
permitted_range += maxf(0.0, blocking.position.x - left_border - jellyfish_width)
left_border = blocking.position.x + blocking.size.x
permitted_range += maxf(0.0, spawning_space.size.x - left_border)
if permitted_range <= 0:
new_jellyfish.queue_free()
return
# Define if the jellyfish is a stimulus or a distraction
var is_stimulus: bool = randf() < _get_difficulty_settings().stimuli_ratio
if is_stimulus:
new_jellyfish.stimulus = _get_current_stimulus()
if is_highlighting:
new_jellyfish.highlight()
else:
var current_distractors: Array = distractions[current_progression % distractions.size()]
new_jellyfish.stimulus = current_distractors.pick_random()
# Randomize the spawn and adds the jellyfish into the scene
var random_spawn: float = randf_range(0, permitted_range - 1)
left_border = 0
# Blocking jellyfish is supposed to be ordered
for blocking: Jellyfish in blocking_jellyfish:
var local_permitted_range: float = maxf(0.0, blocking.position.x - left_border - jellyfish_width)
if local_permitted_range <= random_spawn:
random_spawn -= local_permitted_range
else:
break
left_border = blocking.position.x + blocking.size.x
new_jellyfish.position.x = left_border + random_spawn
new_jellyfish.position.y = spawning_space.size.y
# Insert the new jellyfish on the right spot in the blocking array
var found_ind: int = -1
for index: int in range(blocking_jellyfish.size()):
var blocking: Jellyfish = blocking_jellyfish[index]
if blocking.position.x > new_jellyfish.position.x:
found_ind = index
break
if found_ind < 0:
found_ind = blocking_jellyfish.size()
blocking_jellyfish.insert(found_ind, new_jellyfish)
# Connects the new jellyfish with the pressed signal
new_jellyfish.pressed.connect(_on_stimulus_pressed.bind(new_jellyfish))
func _get_difficulty_settings() -> DifficultySettings:
return difficulty_settings[difficulty]
func _on_current_progression_changed() -> void:
# Play the new stimulus
super()
# Restarts the spawning of jellyfishes
spawn_timer.start()
# ------------ Connections ------------
func _on_spawn_timer_timeout() -> void:
_spawn()
spawn_timer.wait_time = _get_difficulty_settings().spawn_time
func _on_stimulus_pressed(stimulus: Dictionary, node: Node) -> bool:
if not super(stimulus, node):
return false
var jellyfish: Jellyfish = node as Jellyfish
if not jellyfish:
return false
# Disconnect the jellyfish
jellyfish.pressed.disconnect(_on_stimulus_pressed)
# Check if the stimulus is right
var is_right: bool = _is_stimulus_right(jellyfish.stimulus)
if is_right:
jellyfish.happy()
jellyfish.right()
current_progression += 1
_stop_highlight()
else:
jellyfish.hit()
await jellyfish.wrong()
current_lives -= 1
# Play the pressed jellyfish phoneme
if jellyfish.stimulus:
await audio_player.play_syllable(jellyfish.stimulus)
# Remove the jellyfish
await jellyfish.delete()
# Handle the blocking array
if jellyfish in blocking_jellyfish:
blocking_jellyfish.erase(jellyfish)
# Replay the current stimulus
if not is_right:
_play_current_stimulus_phoneme()
return true
func _on_stimulus_found() -> void:
spawn_timer.stop()
# Clear all the jellyfishes
for jellyfish: Jellyfish in spawning_space.get_children():
jellyfish.delete()
blocking_jellyfish.clear()
class DifficultySettings:
var spawn_time: float = 4.0
var stimuli_ratio: float = 0.75
var velocity: int = 150
func _init(p_spawn_time: float, p_stimuli_ratio: float, p_velocity: int) -> void:
spawn_time = p_spawn_time
stimuli_ratio = p_stimuli_ratio
velocity = p_velocity