Skip to main content

Overview

Counting Animals presents players with groups of marine creatures swimming across the screen. Players must count specific animal types and select the correct total from multiple choice options. Difficulty increases by adding more animal types to count simultaneously. Scene Path: res://minigames/counting_animals/scripts/main.gd

Cognitive Skills Developed

  • Numerical Cognition: Counting and number recognition (1-9)
  • Working Memory: Tracking multiple animal types simultaneously
  • Selective Attention: Focusing on target animals while ignoring others
  • Visual Discrimination: Distinguishing between similar-looking creatures
  • Mental Arithmetic: Summing counts across multiple categories

How to Play

Controls

  • Number Buttons: Tap 1-9 to submit your count
  • Back Button: Pause game

Objective

Accurately count the target animal(s) shown before each round and select the correct total.

Gameplay Flow

  1. Instruction Phase: Game shows which animal(s) to count (4 seconds)
  2. Counting Phase: Animals swim across screen; player counts targets
  3. Answer Phase: Player selects number from 1-9 buttons
  4. Feedback: Correct = continue; Wrong = game over

Difficulty Levels

Progression System

var difficulty_level := 1  # 1, 2, or 3
var correct_streak := 0

func start_round():
    var num_types = clamp(difficulty_level, 1, 3)
    current_targets = all_types.slice(0, num_types)
Level 1: Count 1 animal type Level 2: Count 2 animal types simultaneously
Level 3: Count 3 animal types simultaneously

Automatic Progression

func check_difficulty_progression():
    match difficulty_level:
        1:
            if rounds_completed >= 3:
                difficulty_level = 2
        2:
            if rounds_completed >= 5:
                difficulty_level = 3
  • Level 1→2: After 3 consecutive correct answers
  • Level 2→3: After 5 consecutive correct answers

Scoring System

Points by Difficulty

func add_score():
    var points := 0
    match difficulty_level:
        1: points = 10 + ((rounds_completed - 1) * 5)
        2: points = 40 + ((rounds_completed - 1) * 20)
        3: points = 150 + ((rounds_completed - 1) * 30)
    
    score += points
DifficultyBase PointsIncrement per Round
Level 110+5
Level 240+20
Level 3150+30

Coin Conversion

var coins_earned = int(final_score * 2.0)
score_manager.add_coins(coins_earned)
Coins = 2x final score (highest multiplier of all minigames)

Animal Types

var animal_names := {
    "foca": "focas",
    "nyuron_azul": "Nyuron Azules",
    "nyuron_lengua": "Nyuron con lengua",
    "nyuron_soda": "Nyuron Soda",
    "tortuguita": "Tortuguitas",
    "tortuguita_estrella": "Tortuguitas Estrella"
}
Six distinct animal types with unique visual designs:
  • Foca (Seal)
  • Nyuron Azul (Blue Nyuron)
  • Nyuron con Lengua (Nyuron with Tongue)
  • Nyuron Soda (Soda Nyuron)
  • Tortuguita (Little Turtle)
  • Tortuguita Estrella (Star Turtle)

Key Code Examples

Round Initialization

func start_round():
    if is_paused:
        return

    counting = false
    current_targets.clear()

    # Select random animal types based on difficulty
    var num_types = clamp(difficulty_level, 1, 3)
    var all_types = []

    for s in spawner.animals:
        var inst = s.instantiate()
        if "type_id" in inst:
            all_types.append(inst.type_id)
        inst.queue_free()

    all_types.shuffle()
    current_targets = all_types.slice(0, num_types)

    show_instruction(current_targets)
    await get_tree().create_timer(4.0).timeout
    
    instruction_label.text = "¡Empieza!"
    await get_tree().create_timer(1.5).timeout
    
    counting = true
    spawner.start_spawning(current_targets[0])

Animal Preview Display

func show_instruction(animal_type_or_types):
    instruction_label.text = "Animal/es a contar:"
    
    for child in animal_container.get_children():
        child.queue_free()

    var types_to_show = []
    if typeof(animal_type_or_types) == TYPE_STRING:
        types_to_show = [animal_type_or_types]
    else:
        types_to_show = animal_type_or_types

    for t in types_to_show:
        var tex := TextureRect.new()
        tex.expand_mode = TextureRect.EXPAND_IGNORE_SIZE
        tex.stretch_mode = TextureRect.STRETCH_KEEP_ASPECT_CENTERED
        tex.custom_minimum_size = Vector2(64, 64)
        tex.texture = _get_texture_for_animal(t)
        animal_container.add_child(tex)

    animal_container.show()

Answer Verification

func _on_spawn_finished():
    counting = false
    correct_count = 0
    
    await get_tree().create_timer(1.0).timeout
    
    # Sum counts across all target types
    for t in current_targets:
        correct_count += spawner.get_correct_count_for(t.to_lower())
    
    show_answer_choices()

func _on_number_pressed(num_str: String):
    var answer = int(num_str)
    number_buttons.hide()

    if answer == correct_count:
        correct_streak += 1
        rounds_completed += 1
        instruction_label.text = "¡Correcto! Eran %d en total." % correct_count
        add_score()
        check_difficulty_progression()
    else:
        instruction_label.text = "Fallaste eran %d en total." % correct_count
        await get_tree().create_timer(2.0).timeout
        show_game_over()
        return

AnimalSpawner Component

The spawner handles animal movement across the screen:
@onready var spawner = $AnimalSpawner

spawner.connect("spawn_finished", Callable(self, "_on_spawn_finished"))
spawner.start_spawning(current_targets[0])
Key Methods:
  • start_spawning(type_id): Begin spawning animals
  • get_correct_count_for(type): Retrieve count for specific type
  • pause() / resume(): Control spawning during pause

Multiple Choice System

func setup_number_buttons():
    for btn in number_buttons.get_children():
        var num = int(btn.name.replace("btn", ""))
        btn.pressed.connect(_on_number_pressed.bind(str(num)))
Buttons named btn1 through btn9 dynamically connect to verification logic.

Game Over Handling

func show_game_over():
    spawner.stop_spawning()
    counting = false
    get_tree().paused = true

    # Hide all UI elements
    instruction_label.visible = false
    animal_container.visible = false
    number_buttons.hide()
    score_label.hide()

    # Save score
    var final_score = int(score)
    if final_score > 0:
        score_manager.save_high_score("counting_animals", final_score)
        var coins_earned = int(final_score * 2.0)
        score_manager.add_coins(coins_earned)

    panel.visible = true
    title.text = "¡Fin del Juego!"
    points_label.text = "Puntaje: %d" % score

Pause System

func pause_game():
    is_paused = true

    if spawner:
        spawner.process_mode = Node.PROCESS_MODE_DISABLED
        if spawner.has_method("pause"):
            spawner.pause()

    pause_all_animals(true)

func pause_all_animals(pause: bool):
    for animal in get_tree().get_nodes_in_group("spawned_animals"):
        if is_instance_valid(animal):
            if pause:
                animal.process_mode = Node.PROCESS_MODE_DISABLED
                var anim := animal.get_node_or_null("AnimatedSprite2D")
                if anim:
                    anim.speed_scale = 0.0
            else:
                animal.process_mode = Node.PROCESS_MODE_INHERIT
                var anim := animal.get_node_or_null("AnimatedSprite2D")
                if anim:
                    anim.speed_scale = 1.0

Educational Design

Counting Animals uses research-backed techniques:
  • Subitizing: Small numbers (1-3) can be recognized instantly
  • Sequential Counting: Larger quantities require counting strategy
  • Multi-Object Tracking: Level 3 challenges working memory capacity
  • Immediate Feedback: Reinforces correct counting strategies
  • Gradual Difficulty: Builds confidence before increasing complexity

Memorice

Another memory-focused minigame

Minigames Overview

Return to all minigames

Build docs developers (and LLMs) love