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

177 lines
5.3 KiB
GDScript

extends SyllablesMinigame
const HOLE_SCENE: PackedScene = preload("res://sources/minigames/crabs/hole/hole.tscn")
const BACKGROUND_2: CompressedTexture2D = preload("res://assets/minigames/crabs/graphic/background_2.png")
var difficulty_settings: Array[DifficultySettings] = [
DifficultySettings.new(0.75, [2, 1]),
DifficultySettings.new(0.66, [3, 2]),
DifficultySettings.new(0.33, [4, 3]),
DifficultySettings.new(0.25, [4, 3, 2]),
DifficultySettings.new(0.25, [4, 3, 4])
]
var holes: Array[Hole] = []
var stimulus_spawned: bool = false
@onready var crab_zone: Control = $GameRoot/CrabZone
@onready var background: TextureRect = %Background
# Find and set the parameters of the minigame, like the number of lives or the victory conditions.
func _setup_minigame() -> void:
super._setup_minigame()
if randf() < 0.5:
background.texture = BACKGROUND_2
var current_difficulty_settings: DifficultySettings = _get_difficulty_settings()
# Define the rectangular zone where holes will be placed
var zone_top_left: Vector2 = crab_zone.position
var zone_bottom_right: Vector2 = zone_top_left + crab_zone.size
# Loop through each row defined by the difficulty settings
for row_index: int in range(current_difficulty_settings.rows.size()):
# Compute vertical placement ratio (between 0 and 1, skipping the edges)
var vertical_ratio: float = float(row_index + 1) / float(current_difficulty_settings.rows.size() + 1)
var hole_y: float = lerp(zone_top_left.y, zone_bottom_right.y, vertical_ratio)
# Get the number of holes to place in this row
var holes_in_row: int = current_difficulty_settings.rows[row_index]
# Loop through each hole in the current row
for column_index: int in range(holes_in_row):
# Compute horizontal placement ratio (between 0 and 1, skipping the edges)
var horizontal_ratio: float = float(column_index + 1) / float(holes_in_row + 1)
var hole_x: float = lerp(zone_bottom_right.x, zone_top_left.x, horizontal_ratio)
# Instantiate and position the hole
var hole: Hole = HOLE_SCENE.instantiate()
game_root.add_child(hole)
hole.position = Vector2(hole_x, hole_y)
if not Engine.is_editor_hint():
hole.crab_out.connect(_on_hole_crab_out.bind(hole))
hole.stimulus_hit.connect(_on_stimulus_pressed.bind(hole))
hole.crab_despawned.connect(_on_hole_crab_despawned)
stimulus_heard.connect(hole.on_stimulus_heard)
holes.append(hole)
# Launch the minigame
func _start() -> void:
super()
fireworks.set_colors([Color("#7fc8ff"), Color("#f5a8c8"), Color("#bca4ff")])
_spawn_crabs()
func _get_difficulty_settings() -> DifficultySettings:
return difficulty_settings[difficulty]
func _highlight() -> void:
for hole: Hole in holes:
if hole.crab and hole.crab_visible and _is_stimulus_right(hole.crab.stimulus):
hole.highlight()
func _on_stimulus_pressed(stimulus: Dictionary, node: Node) -> bool:
if not super(stimulus, node):
return false
var hole: Hole = node as Hole
if not hole:
return false
var is_right: bool = _is_stimulus_right(stimulus)
if is_right:
hole.right()
current_progression += 1
stimulus_spawned = false
else:
hole.wrong()
current_lives -= 1
# Spawn another crab
_on_hole_crab_despawned(false)
# Play the pressed crab syllable
if stimulus:
await audio_player.play_syllable(stimulus)
await get_tree().create_timer(1).timeout
_play_current_stimulus_phoneme()
return true
func _on_current_progression_changed() -> void:
# Play the new stimulus
super()
# Restarts the spawning of crabs
_spawn_crabs()
# ------------ Crabs ------------
# Spawn a set amount of crabs in random holes
func _spawn_crabs() -> void:
for index: int in range(int(3.0 * holes.size() / 4.0)):
_on_hole_crab_despawned(false)
await get_tree().create_timer(0.1).timeout
func _on_hole_crab_out(hole: Hole) -> void:
if is_highlighting and _is_stimulus_right(hole.crab.stimulus):
hole.highlight()
func _on_hole_crab_despawned(is_stimulus: bool) -> void:
if is_stimulus:
stimulus_spawned = false
if await _await_for_future_or_stimulus_found(get_tree().create_timer(randf_range(0.1, 2.0)).timeout):
return
_on_hole_timer_timeout()
func _on_hole_timer_timeout() -> void:
var holes_range: Array = range(holes.size())
holes_range.shuffle()
var hole_found: bool = false
while not hole_found:
for index: int in holes_range:
if not holes[index].crab:
# Define if the crab is a stimulus or a distraction
# Only one crab with the correct stimulus can be showned at a time
var is_stimulus: bool = not stimulus_spawned and randf() < _get_difficulty_settings().stimuli_ratio
if is_stimulus:
stimulus_spawned = true
holes[index].spawn_crab(_get_current_stimulus(), true)
else:
var current_distractors: Array = distractions[current_progression % distractions.size()]
holes[index].spawn_crab(current_distractors.pick_random() as Dictionary, false)
hole_found = true
break
if not hole_found:
if await _await_for_future_or_stimulus_found(get_tree().create_timer(randf_range(0.1, 0.5)).timeout):
hole_found = true
func _on_stimulus_found() -> void:
# Despawn all the crabs
for hole: Hole in holes:
hole.stop.emit()
class DifficultySettings:
var stimuli_ratio: float = 0.75
var rows: Array[int] = [2, 1]
func _init(p_stimuli_ratio: float, p_rows: Array[int]) -> void:
stimuli_ratio = p_stimuli_ratio
rows = p_rows