Introducción a temas avanzados: Creando un mini-juego tipo Arkanoid en Ren'Py

¡Hola, creadores de novelas visuales! Bienvenidos de nuevo a esta guía de Ren'Py en español. Como prometí en mi [última entrada], hoy comenzamos con temas avanzados que usarán más Python para darle un toque único a tus proyectos. En esta entrada, vamos a crear un **mini-juego básico tipo *Arkanoid***, donde controlaremos una paleta para rebotar una bola y destruir bloques. Implementaremos este mini-juego en un archivo separado (`mini_game.rpy`) y lo integraremos con nuestra novela visual. ¡Empecemos!

1. ¿Qué es *Arkanoid* y qué haremos?
*Arkanoid* es un juego clásico donde controlas una paleta para rebotar una bola y destruir bloques en la pantalla. En esta versión simplificada:
- Tendremos una paleta que se mueve de izquierda a derecha con las teclas.
- Una bola que rebota contra la paleta, las paredes y los bloques.
- Un par de bloques que se destruirán al ser golpeados.
- Condiciones de victoria (destruir todos los bloques) y derrota (la bola cae fuera de la pantalla).

Usaremos Python para manejar la lógica del juego y Ren'Py para mostrar los elementos visuales.


2. Preparativos: Extraer los sprites
Primero, necesitamos los sprites del mini-juego. Usa el sprite sheet que compartí en esta entrada (o busca uno similar en páginas como OpenGameArt). Extrae las siguientes imágenes y guárdalas en la carpeta `game/images`:
- **Paleta**: Usa la barra naranja (segunda fila, primera imagen). Guárdala como `paddle.png`.
- **Bola**: Usa la bola naranja con destellos (cuarta fila, tercera imagen). Guárdala como `ball.png`.
- **Bloque**: Usa el bloque marrón (primera fila, tercera imagen). Guárdalo como `block.png`.

3. Crear el archivo `mini_game.rpy`
Vamos a crear un archivo separado para el mini-juego, siguiendo la estructura de múltiples archivos que aprendimos en el [post del 18 de abril].

1. En la carpeta `game`, crea un nuevo archivo llamado `mini_game.rpy`.
2. Define el mini-juego en este archivo usando una pantalla de Ren'Py y lógica en Python.

4. Código del mini-juego
Aquí está el código completo para `mini_game.rpy`. Explicaré cada sección después.

```
# Definir variables iniciales
default paddle_x = 640 # Posición inicial de la paleta (centro de la pantalla)
default ball_x = 640 # Posición inicial de la bola (centro)
default ball_y = 500 # Posición inicial de la bola (arriba de la paleta)
default ball_speed_x = 5 # Velocidad horizontal de la bola
default ball_speed_y = -5 # Velocidad vertical de la bola
default blocks = [(300, 100), (500, 100)] # Lista de bloques (posición x, y)
default game_over = False # Estado del juego
default game_won = False # Estado de victoria

# Pantalla del mini-juego
screen arkanoid_game():
    # Fondo
    add "bg playa"

    # Paleta (controlada con teclas)
    image "paddle.png":
        xpos paddle_x
        ypos 600
    key "K_LEFT" action SetVariable("paddle_x", max(0, paddle_x - 10))
    key "K_RIGHT" action SetVariable("paddle_x", min(1280 - 100, paddle_x + 10))

    # Bola
    if not game_over and not game_won:
        image "ball.png":
            xpos ball_x
            ypos ball_y

    # Bloques
    for block in blocks:
        image "block.png":
            xpos block[0]
            ypos block[1]

    # Mensajes de victoria/derrota
    if game_over:
        text "¡Perdiste! La bola se cayó.":
            xalign 0.5
            yalign 0.5
        textbutton "Volver":
            xalign 0.5
            yalign 0.6
            action Return()
    elif game_won:
        text "¡Ganaste! Destruiste todos los bloques.":
            xalign 0.5
            yalign 0.5
        textbutton "Volver":
            xalign 0.5
            yalign 0.6
            action Return()

# Lógica del juego en Python
init python:
    def update_game():
        global ball_x, ball_y, ball_speed_x, ball_speed_y, blocks, game_over, game_won
        if game_over or game_won:
            return

        # Mover la bola
        ball_x += ball_speed_x
        ball_y += ball_speed_y

        # Rebote con las paredes
        if ball_x <= 0 or ball_x >= 1280 - 20: # 20 es el ancho de la bola
            ball_speed_x = -ball_speed_x
        if ball_y <= 0:
            ball_speed_y = -ball_speed_y

        # Rebote con la paleta
        paddle_width = 100 # Ancho de la paleta
        if ball_y >= 580 and ball_y <= 600 and ball_x >= paddle_x and ball_x <= paddle_x + paddle_width:
            ball_speed_y = -ball_speed_y

        # Colisión con bloques
        new_blocks = []
        for block in blocks:
            block_x, block_y = block
            block_width = 50 # Ancho del bloque
            block_height = 30 # Alto del bloque
            if (ball_y >= block_y and ball_y <= block_y + block_height and
                ball_x >= block_x and ball_x <= block_x + block_width):
                ball_speed_y = -ball_speed_y # Rebote
            else:
                new_blocks.append(block)
        blocks = new_blocks

        # Verificar victoria
        if not blocks:
            game_won = True

        # Verificar derrota
        if ball_y >= 720:
            game_over = True

# Label para iniciar el mini-juego
label mini_game:
    # Reiniciar variables
    $ paddle_x = 640
    $ ball_x = 640
    $ ball_y = 500
    $ ball_speed_x = 5
    $ ball_speed_y = -5
    $ blocks = [(300, 100), (500, 100)]
    $ game_over = False
    $ game_won = False

    # Mostrar la pantalla del juego
    show screen arkanoid_game

    # Actualizar el juego cada 0.05 segundos
    while not game_over and not game_won:
        $ renpy.pause(0.05)
        $ update_game()

    # Ocultar la pantalla al terminar
    hide screen arkanoid_game
    return
```

5. Explicación del código
- **Variables iniciales**:
  - Definimos variables para la posición de la paleta (`paddle_x`), la bola (`ball_x`, `ball_y`), y su velocidad (`ball_speed_x`, `ball_speed_y`).
  - `blocks` es una lista de tuplas con las posiciones de los bloques.
  - `game_over` y `game_won` controlan el estado del juego.

- **Pantalla del mini-juego** (`screen arkanoid_game`):
  - Mostramos un fondo (`bg playa`, que ya usamos antes).
  - La paleta (`paddle.png`) se mueve con las teclas izquierda y derecha.
  - La bola (`ball.png`) se posiciona según las variables `ball_x` y `ball_y`.
  - Los bloques (`block.png`) se muestran según la lista `blocks`.
  - Mostramos mensajes de victoria o derrota cuando el juego termina.

- **Lógica del juego** (`update_game`):
  - Esta función en Python actualiza la posición de la bola.
  - Maneja rebotes con las paredes y la paleta.
  - Detecta colisiones con los bloques y los elimina.
  - Verifica si el jugador gana (todos los bloques destruidos) o pierde (la bola cae).

- **Label `mini_game`**:
  - Reinicia las variables al comenzar.
  - Muestra la pantalla del juego y actualiza la lógica cada 0.05 segundos.
  - Termina cuando el jugador gana o pierde.

6. Integrar el mini-juego en tu novela visual
Para llamar al mini-juego desde tu historia, modifica `script.rpy` (del proyecto del 18 de abril) y añade una llamada al mini-juego en algún punto. Por ejemplo:

```
label start:
    scene bg playa with fade
    call definiciones
    call rutas
    call finales
    call mini_game # Añade esta línea
    return
```

7. Probar el mini-juego
1. Guarda las imágenes (`paddle.png`, `ball.png`, `block.png`) en `game/images`.
2. Crea `mini_game.rpy` con el código proporcionado.
3. Modifica `script.rpy` para incluir `call mini_game`.
4. Ejecuta tu proyecto en Ren'Py y juega el mini-juego:
   - Usa las teclas izquierda y derecha para mover la paleta.
   - Intenta destruir los bloques con la bola.
   - Verifica que el juego termine si ganas o pierdes.

8. Ejercicio: Personaliza el mini-juego
Ahora te toca a ti. Usa este código como base y personaliza tu mini-juego:
- Añade más bloques (por ejemplo, `blocks = [(300, 100), (500, 100), (400, 150)]`).
- Cambia la velocidad de la bola ajustando `ball_speed_x` y `ball_speed_y`.
- Usa diferentes sprites del sprite sheet para la bola o los bloques.
- Añade un mensaje introductorio antes de que empiece el mini-juego (por ejemplo, Perrito diciendo: "¡Vamos a jugar un juego!").

9. ¡Tu turno!
Copia este código en tu proyecto y prueba el mini-juego. ¿Lograste destruir los bloques? ¿Cómo te fue con las colisiones? 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