小游戏
介绍如何在Pixi'VN中集成小游戏,涵盖最佳实践、生命周期管理,以及基于PixiJS与React的示例实现。
点击上方按钮,你还可以用 AI 快速生成属于自己的小游戏原型。
相比纯文字叙述,互动故事的魅力在于:玩家可以在剧情间隙稍作休息,通过小游戏与故事世界产生更深的互动。
在视觉小说中,小游戏通常作为剧情的延伸被触发。 为了在叙事界面与小游戏界面之间平滑切换,推荐将小游戏绑定到独立路由(例如 /minigame),并在剧情中通过导航跳转进入。 更多路由配置细节请参阅此处。
这里有一些提示:
- 善用
@drincs/pixi-vn/pixi.js提供的子模块:如 Graphics、Sprite、Text 等组件,可快速构建游戏画面。@drincs/pixi-vn/pixi.js本质是PixiJS的封装导入,因此你可自由使用 PixiJS 的全部能力。 - 使用PixiJS Layers为小游戏创建独立图层。 这样,你就可以将其与视觉小说主界面解耦管理。
- 通过
Ticker类控制帧更新,同步处理游戏状态变化。 - 借助
window.addEventListener响应键盘、鼠标等交互事件。 - 使用HTML元素创建UI,如按钮、分数面板、游戏结束提示等。
- Pixi'VN不会自动保存图层状态,如果使用PixiJS Layers,请自行管理小游戏的状态 将状态保存在变量中,并在小游戏重新启动时恢复。
Templates
useMinigame是一个自定义钩子,可帮助管理小游戏的生命周期,包括启动、更新和清理资源。 它已存在于所有模板。
例如:
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>
)}
</>
);
}下面举几个例子:
Pixi'VN团队非常欢迎新的创意与代码贡献,共同让这套工具链更加完善。 欢迎在下面的聊天中分享或提出你自己的小游戏实施方案!