Pixi’VN

Minigiochi

Guida all'integrazione dei minigiochi in Pixi’VN, che include best practice, gestione del ciclo di vita e implementazioni di esempio utilizzando PixiJS e React.

IA

Puoi usare il pulsante sopra per creare il tuo minigioco, con l'AI.

Il bello di una storia interattiva rispetto al testo normale è che puoi prenderti una pausa e interagire con minigiochi legati alla storia.

I minigiochi nelle visual novel vengono generalmente avviati durante la narrazione. Per passare dall'UI narrativa all'UI del minigioco, si consiglia di collegare il minigioco a una route (ad es., "/minigame/snake") e navigare verso di essa dalla storia. Maggiori informazioni sono disponibili qui.

Ecco alcuni consigli:

  • Usa PixiJS direttamente — sia il pacchetto pixi.js stesso, sia il sottomodulo @drincs/pixi-vn/pixi.js che lo ri-esporta — con componenti come Graphics, Sprite e Text, combinati con Livelli PixiJS per creare un livello separato per il tuo minigioco, gestito in modo indipendente dall'interfaccia principale della visual novel.
  • Usa gli hotkeys per gestire l'input da tastiera per i controlli del tuo minigioco. Consulta Hotkeys per scoprire come configurarli.
  • Si consiglia sempre di non usare PixiJS per costruire l'UI (pulsanti, visualizzazioni del punteggio, messaggi di game over, ...); usa invece un framework come React o Vue.
  • Salvare e ripristinare lo stato attuale del minigioco è responsabilità dello sviluppatore.
  • Dato che un minigioco è una route a sé stante, un progetto di solito finisce per averne più di uno sotto lo stesso percorso /minigame (ad es. /minigame/snake, /minigame/quiz); usa il routing basato su file di TanStack Router per condividere la logica tra di essi invece di duplicarla in ogni minigioco (vedi sotto).
  • Avviare un minigioco non è altro che navigare verso la sua route dalla storia; se necessita di un parametro (una difficoltà, un ID livello, ...), passalo tramite la stessa route (vedi sotto).

Modelli

useMinigame è un hook personalizzato che ti aiuta a gestire il ciclo di vita di un minigioco, incluso l'avvio, l'aggiornamento e la pulizia delle risorse. È presente in tutti i template.

Ad esempio:

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>
            )}
        </>
    );
}

Esempi

Il team di Pixi’VN accoglie con favore nuove proposte e contributi per rendere questa libreria ancora più completa. Sentiti libero di condividere o proporre le tue implementazioni di minigiochi nella chat qui sotto!

In questa pagina