Minigames
Guide to integrating minigames into Pixi’VN, including best practices, lifecycle management, and example implementations using PixiJS and React.
The beauty of an interactive story compared to normal text is that you can take a break and interact with minigames related to the story.
Minigames in visual novels are typically launched during the narrative. To switch between the narrative UI and the minigame UI, it is recommended to link the minigame to a route (e.g., "/minigame") and navigate to it from the story. More information is available here.
Here are some tips:
- Use components provided by the
@drincs/pixi-vn/pixi.js
submodule, such asGraphics
,Sprite
, andText
, to create your minigame.@drincs/pixi-vn/pixi.js
is the PixiJS import, so you can use all its features. - Use PixiJS Layers to create a separate layer for your minigame. This allows you to manage the minigame independently from the main visual novel interface.
- Use the
Ticker
class to manage the game loop and update the game state. - Use
window.addEventListener
to handle user input, such as keyboard or mouse events. - Use HTML elements to create the UI, such as buttons, score displays, and game over messages.
- If you use PixiJS Layers, remember that Pixi’VN does not save the state of layers, so you need to manage the minigame state yourself. Save the state in a variable and restore it when the minigame restarts.
useMinigame
is a custom hook that helps you manage the lifecycle of a minigame, including starting, updating, and cleaning up resources. It is present in all templates.
For example:
import { Layer } from "@drincs/pixi-vn";
import { Graphics, Ticker } from "@drincs/pixi-vn/pixi.js";
import { useCallback, useMemo, useRef, useState } from "react";
import useMinigame from "../hooks/useMinigame";
export default function MiniGame() {
const ticker = useMemo(() => new Ticker(), []);
const [displayScore, setDisplayScore] = useState(0);
const [gameOver, setGameOver] = useState(false);
const onKeyDown = useCallback((e: KeyboardEvent) => {
// Handle key down events for game controls
}, []);
const game = useCallback(
(layer: Layer) => {
const endGame = () => {
ticker.stop();
setGameOver(true);
};
window.addEventListener("keydown", onKeyDown);
ticker.add(({ deltaMS }) => {
// Update game logic here
});
ticker.start();
},
[ticker] // They must not be changed during the game otherwise the game will restart
);
const options = useMemo(
() => ({
onExit() {
ticker.stop();
ticker.destroy();
window.removeEventListener("keydown", onKeyDown);
},
}),
[ticker, onKeyDown] // 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>
)}
</>
);
}
Here are some examples:
The Pixi’VN Team welcomes new proposals and contributions to make this library even more complete. You can create a discussion to share or propose your minigame implementations.