Pixi’VN

Minijuegos

Guía para integrar minijuegos en Pixi’VN, incluyendo buenas prácticas, gestión del ciclo de vida e implementaciones de ejemplo utilizando PixiJS y React.

IA

Puedes usar el botón de arriba para crear tu propio minijuego, con IA.

La belleza de una historia interactiva en comparación con el texto normal es que puedes tomar un descanso e interactuar con minijuegos relacionados con la historia.

Los minijuegos en las visual novels normalmente se lanzan durante la narrativa. Para cambiar entre la UI narrativa y la UI del minijuego, se recomienda vincular el minijuego a una ruta (por ejemplo, "/minigame/snake") y navegar a ella desde la historia. Más información está disponible aquí.

Aquí tienes algunos consejos:

  • Usa PixiJS directamente — ya sea el paquete pixi.js en sí o el submódulo @drincs/pixi-vn/pixi.js que lo reexporta — con componentes como Graphics, Sprite y Text, combinado con PixiJS Layers para crear una capa separada para tu minijuego, gestionada de forma independiente de la interfaz principal de la visual novel.
  • Usa hotkeys para gestionar la entrada de teclado de los controles de tu minijuego. Consulta Hotkeys para aprender a configurarlas.
  • Siempre se recomienda no usar PixiJS para construir la UI (botones, marcadores de puntuación, mensajes de fin de partida, ...); usa en su lugar un framework como React o Vue.
  • Guardar y restaurar el estado actual del minijuego es responsabilidad del desarrollador.
  • Dado que un minijuego es su propia ruta, un proyecto normalmente termina teniendo más de uno bajo la misma ruta /minigame (por ejemplo, /minigame/snake, /minigame/quiz); usa el enrutamiento basado en archivos de TanStack Router para compartir lógica entre ellos en lugar de duplicarla en cada minijuego (ver más abajo).
  • Iniciar un minijuego no es más que navegar a su ruta desde la historia; si necesita un parámetro (una dificultad, un id de nivel, ...), pásalo a través de esa misma ruta (ver más abajo).

Plantillas

useMinigame es un hook personalizado que te ayuda a gestionar el ciclo de vida de un minijuego, incluyendo el inicio, la actualización y la limpieza de recursos. Está presente en todas las plantillas.

Por ejemplo:

src/routes/minigame/example.tsx
import { Layer } from "@drincs/pixi-vn";
import { Graphics, Ticker } from "@drincs/pixi-vn/pixi.js";
import { createFileRoute } from "@tanstack/react-router";
import { useCallback, useMemo, useState } from "react";
import { useHotkey } from "@tanstack/react-hotkeys";
import useMinigame from "@/lib/hooks/minigame-hooks";

export const Route = createFileRoute("/minigame/example")({
    component: MiniGame,
});

function MiniGame() {
    const [displayScore, setDisplayScore] = useState(0);
    const [gameOver, setGameOver] = useState(false);

    const ticker = useMemo(() => {
        const ticker = new Ticker();

        const endGame = () => {
            ticker.stop();
            setGameOver(true);
        };

        ticker.add(({ deltaMS }) => {
            // Update game logic here
        });

        return ticker;
    }, []);

    useHotkey(
        "ArrowUp",
        () => {
            // Handle key down events for game controls
        },
        { enabled: !gameOver },
    );

    const game = useCallback(
        (layer: Layer) => {
            ticker.start();
        },
        [ticker], // They must not be changed during the game otherwise the game will restart
    );

    const options = useMemo(
        () => ({
            onExit() {
                ticker.stop();
                ticker.destroy();
            },
        }),
        [ticker], // They must not be changed during the game otherwise the game will restart
    );

    const { loading } = useMinigame(game, options);

    return (
        <>
            <div
                style={{
                    position: "absolute",
                    top: 10,
                    left: 10,
                    color: "white",
                    fontSize: "24px",
                    background: "rgba(0,0,0,0.5)",
                    padding: "5px 10px",
                    borderRadius: "5px",
                }}
            >
                Score: {displayScore}
            </div>

            {gameOver && (
                <div
                    style={{
                        position: "absolute",
                        top: "50%",
                        left: "50%",
                        transform: "translate(-50%, -50%)",
                        color: "red",
                        fontSize: "48px",
                        background: "rgba(0,0,0,0.7)",
                        padding: "20px 40px",
                        borderRadius: "10px",
                    }}
                >
                    GAME OVER
                </div>
            )}
        </>
    );
}

Ejemplos

El equipo de Pixi’VN da la bienvenida a nuevas propuestas y contribuciones para hacer esta biblioteca aún más completa. ¡No dudes en compartir o proponer tus implementaciones de minijuegos en el chat de abajo!

En esta página