Pixi’VN

Мини-игры

Руководство по интеграции мини-игр в Pixi’VN, включая лучшие практики, управление жизненным циклом и примеры реализации с использованием PixiJS и React.

ИИ

Вы можете использовать кнопку выше, чтобы создать свою собственную мини-игру с помощью ИИ.

Прелесть интерактивной истории по сравнению с обычным текстом в том, что вы можете сделать паузу и взаимодействовать с мини-играми, связанными с историей.

Мини-игры в visual novel обычно запускаются во время повествования. Чтобы переключаться между UI повествования и UI мини-игры, рекомендуется привязать мини-игру к маршруту (например, "/minigame/snake") и переходить к нему из истории. Более подробная информация доступна здесь.

Вот несколько советов:

  • Используйте PixiJS напрямую — либо сам пакет pixi.js, либо подмодуль @drincs/pixi-vn/pixi.js, который его реэкспортирует — с такими компонентами, как Graphics, Sprite и Text, в сочетании с слоями PixiJS, чтобы создать отдельный слой для вашей мини-игры, управляемый независимо от основного интерфейса visual novel.
  • Используйте hotkeys для обработки ввода с клавиатуры для управления вашей мини-игрой. См. Hotkeys, чтобы узнать, как их настроить.
  • Всегда рекомендуется не использовать PixiJS для создания UI (кнопки, отображение счёта, сообщения об окончании игры, ...); вместо этого используйте такой фреймворк, как React или Vue.
  • Сохранение и восстановление текущего состояния мини-игры — обязанность разработчика.
  • Поскольку мини-игра — это отдельный маршрут, в проекте обычно оказывается несколько таких маршрутов под одним и тем же путём /minigame (например, /minigame/snake, /minigame/quiz); используйте файловую маршрутизацию TanStack Router, чтобы разделять логику между ними вместо её дублирования в каждой мини-игре (см. ниже).
  • Запуск мини-игры — это не что иное, как переход к её маршруту из истории; если ей нужен параметр (сложность, ID уровня, ...), передайте его через тот же маршрут (см. ниже).

Шаблоны

useMinigame — это пользовательский хук, который помогает управлять жизненным циклом мини-игры, включая запуск, обновление и очистку ресурсов. Он присутствует во всех шаблонах.

Например:

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

Примеры

Команда Pixi’VN приветствует новые предложения и вклад, чтобы сделать эту библиотеку ещё более полной. Не стесняйтесь делиться или предлагать свои реализации мини-игр в чате ниже!

На этой странице