Temas avanzados: Implementar un medidor de días con acciones en Ren'Py

¡Hola, creadores de novelas visuales! En nuestra [entrada anterior], añadimos *easter eggs* interactivos para darle rejugabilidad a nuestras historias. Hoy vamos a explorar otra mecánica avanzada: **un medidor de días con puntos de acción (AP)**. Crearemos un sistema donde el tiempo avanza según las acciones del jugador, activaremos eventos específicos en ciertos días, y aprenderemos a evitar problemas como bucles infinitos. ¡Empecemos!

1. ¿Qué es un medidor de días y por qué usarlo?
Un medidor de días simula el paso del tiempo en tu novela visual. Es útil para:
- Darle estructura a la historia (por ejemplo, "tienes 7 días para completar una misión").
- Activar eventos específicos en ciertos días (como un festival el día 3).
- Aumentar la inmersión al hacer que las acciones del jugador tengan consecuencias temporales.

Vamos a usar una variable `dias` para rastrear el día actual y una variable `AP` (Action Points) para medir las acciones del jugador. Cuando se consuma una cantidad fija de AP (por ejemplo, 3), avanzaremos un día.

2. Preparativos
Usaremos el proyecto de Perrito y Gatita (del [post del 18 de abril]). Necesitaremos:
- Los archivos existentes (`script.rpy`, `definiciones.rpy`, `rutas.rpy`, `finales.rpy`).
- Una variable `dias` para rastrear el día actual.
- Una variable `AP` para los puntos de acción.

3. Crear un archivo para el medidor de días
Para mantener el proyecto organizado, crearemos un archivo `day_system.rpy` que manejará la lógica del medidor de días.

1. En la carpeta `game`, crea un nuevo archivo llamado `day_system.rpy`.
2. Define las variables y la pantalla para el medidor.

4. Código para el medidor de días
Aquí está el código para `day_system.rpy`:

```
# Definir variables
default dias = 1 # Día inicial
default AP = 3 # Puntos de acción iniciales
default actions_per_day = 3 # Acciones necesarias para avanzar un día
default event_triggered = False # Para rastrear eventos específicos

# Pantalla para mostrar el medidor de días y AP
screen day_meter():
    frame:
        xalign 0.5
        yalign 0.05
        hbox:
            text "Día: [dias] AP: [AP]"

# Función para gastar AP y avanzar días
init python:
    def spend_action(amount):
        global AP, dias
        AP -= amount
        if AP <= 0:
            dias += 1
            AP = actions_per_day # Reinicia los AP para el nuevo día

# Label para manejar eventos específicos
label day_events:
    if dias == 3 and not event_triggered:
        $ event_triggered = True
        scene bg playa with dissolve
        show perrito at left
        show gatita at right
        narrator "Es el día 3, y Perrito y Gatita deciden organizar un picnic especial."
        perrito "¡Mira, Gatita! Preparé una canasta con nuestras comidas favoritas."
        gatita "¡Qué divertido! Vamos a comer bajo ese árbol."
    return
```

5. Integrar el medidor de días en tu novela visual
Vamos a modificar el proyecto existente para incluir el medidor de días y los eventos condicionales.

1. **Añadir las variables iniciales**:
   - En `definiciones.rpy`, añade las variables:
     ```
     default dias = 1
     default AP = 3
     default actions_per_day = 3
     default event_triggered = False
     ```

2. **Mostrar el medidor en pantalla**:
   - En `rutas.rpy`, muestra la pantalla del medidor al inicio de las rutas:
     ```
     label rutas:
         play music audio.playa_musica loop
         scene bg playa with dissolve
         show screen easter_egg_playa
         show screen day_meter # Añade esta línea
         show perrito at left
         show gatita at right
         narrator "Perrito y Gatita están en la playa, listos para pasar el día juntos."

         perrito "¡Hola, Gatita! ¿Qué quieres hacer primero?"
         menu:
             "Explorar una cueva.":
                 $ spend_action(1) # Gasta 1 AP
                 $ puntos_amistad += 10
                 scene bg cueva with dissolve
                 narrator "Perrito y Gatita entran a una cueva oscura."
                 perrito "¡Qué aventura!"
                 gatita "Es un poco scary, pero contigo me siento bien."
                 play sound audio.sorpresa
                 call day_events # Verifica eventos después de cada acción
             "Jugar en la arena.":
                 $ spend_action(1) # Gasta 1 AP
                 $ puntos_amistad += 5
                 scene bg playa with dissolve
                 narrator "Perrito y Gatita construyen un castillo de arena."
                 perrito "¡Mira qué alto quedó!"
                 gatita "¡Es el mejor castillo que hemos hecho!"
                 call day_events

         perrito "¿Y ahora qué hacemos?"
         menu:
             "Compartir un helado.":
                 $ spend_action(1) # Gasta 1 AP
                 $ puntos_amistad += 10
                 narrator "Perrito y Gatita comparten un helado de vainilla."
                 gatita "¡Qué rico! Gracias por compartir, Perrito."
                 call day_events
             "Caminar solos por la playa.":
                 $ spend_action(1) # Gasta 1 AP
                 $ puntos_amistad -= 5
                 narrator "Perrito y Gatita caminan separados, cada uno en sus pensamientos."
                 gatita "Está bien, pero me habría gustado estar más juntos..."
                 call day_events

         return
     ```

3. **Ajustar los finales para reflejar los días**:
   - En `finales.rpy`, puedes añadir un mensaje que mencione el día final:
     ```
     label finales:
         scene bg playa with fade
         show perrito at left
         show gatita at right
         narrator "El día [dias] en la playa termina. Veamos cómo les fue a Perrito y Gatita."
         # ... el resto del código sigue igual ...
     ```

6. Precauciones: Evitar bucles infinitos y declarar variables correctamente
Cuando uses un sistema como este, ten cuidado con:
- **Declarar variables**:
  - Usa `default` para definir las variables iniciales (como `default dias = 1`), no `define`, ya que `define` es para constantes que no cambian.
  - Asegúrate de que todas las variables estén definidas antes de usarlas para evitar errores como "NameError: name 'dias' is not defined".
- **Evitar bucles infinitos**:
  - Si usas un bucle (como `while`), siempre incluye una condición de salida. Por ejemplo, en nuestro mini-juego del 1 de mayo, usamos `while not game_over and not game_won` para asegurarnos de que el juego termine.
  - En este sistema, el avance del día está controlado por `spend_action`, así que no hay bucles. Pero si añades un bucle (por ejemplo, para repetir acciones), asegúrate de que haya una forma de salir (como un límite de días o AP).
- **Prueba cuidadosamente**:
  - Ejecuta tu juego después de cada cambio para verificar que los días avancen correctamente y que los eventos se activen como esperas.

7. Ejercicio: Personaliza tu medidor de días
Ahora te toca a ti. Usa este código como base y personaliza tu sistema:
- Cambia la cantidad de AP necesaria para avanzar un día (por ejemplo, `actions_per_day = 5`).
- Añade otro evento especial (por ejemplo, un evento el día 5 donde Perrito y Gatita encuentran un tesoro).
- Modifica el diseño del medidor (por ejemplo, cambia los colores o la posición del `frame` en `day_meter`).
- Crea una situación donde el juego termine si llegas al día 7 (por ejemplo, mostrando un mensaje como "¡Se acabó el tiempo!").

8. ¡Tu turno!
Añade este código a tu proyecto y prueba el medidor de días. ¿Los días avanzaron correctamente después de gastar AP? ¿Pudiste activar el evento del día 3? Intenta los ejercicios y comparte tus resultados en los comentarios. En la próxima entrada, seguiremos explorando temas avanzados, como insertar videos cortos o crear sistemas de guardado personalizados. ¡Nos leemos pronto!


Comentarios

Entradas más populares de este blog

Introducción a Ren'Py - Tu primer paso para crear novelas visuales

Importar un segundo personaje y hacer que interactúen en Ren'Py

Crear rutas alternas con el comando `if` en Ren'Py