미니게임
PixiJS와 React를 사용하여 모범 사례, 생명주기 관리, 예제 구현을 포함해 Pixi’VN에 미니게임을 통합하는 방법에 대한 가이드입니다.
AI
위의 버튼을 사용하여 AI로 나만의 미니게임을 만들 수 있습니다.
일반 텍스트와 비교했을 때 인터랙티브 스토리의 매력은 잠시 쉬어가며 스토리와 관련된 미니게임을 즐길 수 있다는 점입니다.
비주얼 노벨의 미니게임은 일반적으로 내러티브 진행 중에 실행됩니다. 내러티브 UI와 미니게임 UI 사이를 전환하려면, 미니게임을 라우트(예: "/minigame/snake")에 연결하고 스토리에서 그 라우트로 이동하는 것이 권장됩니다. 더 자세한 정보는 여기에서 확인할 수 있습니다.
다음은 몇 가지 팁입니다:
- PixiJS를 직접 사용하세요 —
pixi.js패키지 자체 또는 이를 재내보내는@drincs/pixi-vn/pixi.js서브모듈 중 하나를Graphics,Sprite,Text와 같은 컴포넌트와 함께 사용하고, PixiJS Layers와 결합하여 메인 비주얼 노벨 인터페이스와 독립적으로 관리되는 미니게임 전용 레이어를 만드세요. - 미니게임 조작을 위한 키보드 입력을 처리하려면 Hotkeys를 사용하세요. 설정 방법을 알아보려면 Hotkeys를 참조하세요.
- UI(버튼, 점수 표시, 게임 오버 메시지 등)를 만들 때는 PixiJS를 사용하지 않는 것이 항상 권장됩니다. 대신 React나 Vue와 같은 프레임워크를 사용하세요.
- 미니게임의 현재 상태를 저장하고 복원하는 것은 개발자의 책임입니다.
- 미니게임은 그 자체로 하나의 라우트이기 때문에, 프로젝트에서는 보통 동일한
/minigame경로 아래에 여러 개의 미니게임(예:/minigame/snake,/minigame/quiz)이 존재하게 됩니다. 각 미니게임마다 로직을 중복 작성하는 대신 TanStack Router의 파일 기반 라우팅을 사용하여 로직을 공유하세요(자세한 내용은 아래 참조). - 미니게임을 시작하는 것은 스토리에서 해당 라우트로 이동하는 것에 지나지 않습니다. 매개변수(난이도, 레벨 ID 등)가 필요하다면, 동일한 라우트를 통해 전달하세요(아래 참고).
템플릿
useMinigame은 시작, 업데이트, 리소스 정리를 포함하여 미니게임의 생명주기를 관리하는 데 도움을 주는 커스텀 훅입니다. 모든 템플릿에 포함되어 있습니다.
예를 들어:
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 팀은 이 라이브러리를 더욱 완성도 있게 만들기 위한 새로운 제안과 기여를 환영합니다. 아래 채팅에서 여러분의 미니게임 구현을 자유롭게 공유하거나 제안해 주세요!