更新记录
1.0.0(2026-06-24) 下载此版本
作为 1.0.0 起始版本,初始化 jz-gameManager 通用游戏管理器插件,面向 uni-app 场景,采用 分层架构 + Facade 模式 + 事件驱动 设计,提供统一入口 GameManager 单例。
核心层(core)
GameManager:单例门面,统一管理子模块与生命周期,提供createGameManager()/getGameManager()/destroyGameManager()/configure()/dispose()等入口方法,并聚合状态、模式、数据、计时器、音效、音乐、朗读、随机数、分数、多人联机的便捷 API。GameStateMachine:游戏状态机,内置 11 种通用状态(idle / ready / loading / playing / paused / round-start / round-end / intermission / waiting / game-over / error)与默认跳转规则,支持自定义状态、跳转规则、快照导出 / 恢复。GameModeManager:游戏模式管理,支持单机 / 多人联机 / 对战 / 合作四种模式以及realtimeSync / roomManagement / playerDataSync / voiceChat / hostAuthoritative等特性查询。GameTimerManager:计时器管理,支持倒计时、正计时、回合计时、间隔触发器,统一暂停 / 继续 / 停止,多计时器并行。GameDataManager:数据管理,提供运行时内存、本地持久化、房间数据同步、玩家数据同步、多槽位进度存档、自动保存、数据导入 / 导出能力。MultiplayerManager:多人联机管理,房间创建 / 加入 / 离开、玩家管理、消息收发、状态同步、自定义消息处理器、请求-响应通讯、踢人等能力。
适配层(adapters)
ConnectProvider:多人联机抽象接口,定义init / send / broadcast / request / kick / getPeerId / getPeers / on / off / dispose契约。业务侧通过实现该接口可对接任意 WebRTC 方案(推荐基于jz-webrtc-connect包装),实现核心逻辑与具体通讯实现的解耦。
数据层(data)
GameStoreBase:数据存储基类,提供版本号、变更通知、patch / snapshot / restore 协议。PlayerStore/RoomStore/ProgressStore:玩家数据、房间数据、进度存档专用 Store。StorageDriver:内置MemoryDriver(运行时内存)与UniStorageDriver(基于uni.setStorage持久化)两种驱动。
工具层(utils)
SoundPlayer:音效播放器,支持多实例并发、音量控制、循环播放。MusicPlayer:背景音乐播放器,支持渐入渐出、暂停 / 继续 / 切换、队列管理。TextReader:文字朗读器,基于 Web Speech API,可设置语速、音调、音量、语言。RandomGenerator:随机数生成器,支持种子随机(可复现的 LCG 算法)、范围整数 / 浮点、概率随机、权重抽取、洗牌、随机选择。GameScoreManager:分数管理器,支持多玩家分数管理、排行榜、历史最高分、分数变更事件、自定义排序规则。FrameAnimationPlayer:帧动画播放器,提供fromFramesByDir / fromSpriteSheet / fromAnimations三种创建方式,支持ONCE / LOOP / PINGPONG三种循环模式,提供位置、缩放、旋转、锚点、透明度等节点属性,可在 requestAnimationFrame 循环中以update(deltaMs)推进。
通用层(common)
EventBus:轻量事件总线,不依赖 Vue / Node,提供on / off / once / emit / clear。GameError:统一错误对象,附带ERROR_CODES错误码枚举。constants:状态、模式、消息类型、计时器类型、帧动画循环模式、版本号等枚举常量。utils:UUID 生成、深度合并、防抖、节流、时间戳等通用工具函数。
入口
index.js:统一导出全部公开 API、类、枚举常量,便于业务侧按需引入。- 提供顶层便捷函数:
createGameManager / getGameManager / destroyGameManager / configure / getConfig。
平台与依赖
- 单机功能(状态机、计时器、数据、音效、随机数、分数、帧动画):无第三方依赖,全平台支持(H5 / App / 小程序)。
- 多人联机功能:依赖业务侧实现
ConnectProvider,受 WebRTC 限制仅 H5 环境可用;推荐配合jz-webrtc-connect插件使用。
配套示例
- 工程同步提供 7 个 Demo 页面(基础功能、分数管理、随机数、计时器、数据存储、帧动画、剪刀石头布多人对战),覆盖全部核心能力,可直接运行查看效果。
平台兼容性
uni-app(4.74)
| Vue2 | Vue3 | Chrome | Safari | app-vue | app-nvue | Android | iOS | 鸿蒙 |
|---|---|---|---|---|---|---|---|---|
| - | √ | √ | √ | √ | √ | √ | √ | √ |
| 微信小程序 | 支付宝小程序 | 抖音小程序 | 百度小程序 | 快手小程序 | 京东小程序 | 鸿蒙元服务 | QQ小程序 | 飞书小程序 | 小红书小程序 | 快应用-华为 | 快应用-联盟 |
|---|---|---|---|---|---|---|---|---|---|---|---|
| √ | - | - | - | - | - | - | - | - | - | × | × |
jz-gameManager
jz-gameManager 是一个面向 uni-app 的通用游戏管理器插件,提供开箱即用的游戏开发基础能力,让业务代码聚焦于「玩法」本身。
- 版本:
1.0.0 - 入口:
@/uni_modules/jz-gameManager - 平台:单机能力全平台支持;多人联机能力依赖 WebRTC,仅 H5 可用
目录
核心能力
- 游戏状态机:内置通用状态与跳转规则,支持自定义状态与跳转路径
- 游戏模式管理:单机 / 多人联机 / 对战 / 合作四种模式,按模式查询特性
- 计时器管理:倒计时、正计时、回合计时、间隔触发,统一暂停/继续/停止
- 数据管理:本地持久化(uni Storage)、运行时内存、房间数据同步、玩家数据同步、多槽位进度存档
- 多人联机:基于自定义
ConnectProvider适配层,可对接任意 WebRTC 方案 - 音效 / 音乐 / 朗读:统一封装的
SoundPlayer/MusicPlayer/TextReader - 随机数生成:支持种子随机(可复现)与普通随机
- 分数管理:玩家分数、排行榜、历史最高分
- 帧动画:基于 requestAnimationFrame 的帧动画播放器,支持循环 / 乒乓 / 单次
架构
采用 分层架构 + Facade 模式 + 事件驱动 设计:
入口层 index.js
└─ 核心层 core/ GameManager / GameStateMachine / GameModeManager
GameDataManager / MultiplayerManager / GameTimerManager
├─ 工具层 utils/ SoundPlayer / MusicPlayer / TextReader
RandomGenerator / GameScoreManager / FrameAnimationPlayer
├─ 数据层 data/ GameStoreBase / PlayerStore / RoomStore / ProgressStore / StorageDriver
├─ 适配层 adapters/ ConnectProvider(多人联机抽象接口)
└─ 通用层 common/ EventBus / GameError / constants / utils
GameManager 作为单例门面,统一管理所有子模块并通过 EventBus 分发事件。
安装与依赖
将插件复制到工程的 uni_modules 目录即可:
src/uni_modules/jz-gameManager/
- 单机能力(状态机、计时器、数据、音效、随机数、分数、帧动画):无第三方依赖,全平台可用
- 多人联机能力:需要业务侧自行实现
ConnectProvider,并注入到GameManager- 推荐基于
jz-webrtc-connect封装(已在示例src/pages/game/rps中实现) - 仅 H5(Chrome / Safari)环境可用
- 推荐基于
快速开始
单机模式
import { createGameManager, GAME_STATE, GAME_MODE } from '@/uni_modules/jz-gameManager'
const game = await createGameManager({
gameId: 'my-game',
mode: GAME_MODE.SINGLE,
initialState: GAME_STATE.IDLE,
sounds: { click: '/static/sounds/click.mp3' },
music: { bgm: '/static/music/bgm.mp3' }
})
// 监听状态变更
game.on('state-change', e => console.log(e.prev, '->', e.next))
// 切换状态(跳转受状态机规则约束)
game.setState(GAME_STATE.READY)
game.setState(GAME_STATE.PLAYING)
// 播放音效 / 音乐
game.playSound('click')
game.playBGM('bgm')
// 倒计时
game.startCountdown({
duration: 60,
onTick: remaining => console.log('剩余', remaining),
onEnd: () => console.log('时间到')
})
// 本地数据持久化
game.setLocalData('score', 100)
game.getLocalData('score') // 100
// 页面销毁时
await game.dispose()
多人联机模式
import { createGameManager, GAME_MODE, ConnectProvider } from '@/uni_modules/jz-gameManager'
// 1. 自行实现 ConnectProvider(示例见 src/pages/game/rps/composables/RpsConnectAdapter.js)
class MyAdapter extends ConnectProvider { /* ... */ }
const adapter = new MyAdapter(coreInstance)
// 2. 注入到 GameManager
const game = await createGameManager({
gameId: 'my-game',
mode: GAME_MODE.MULTIPLAYER,
adapter
})
// 3. 房主创建房间
const { roomId } = await game.createRoom({
playerInfo: { name: '玩家1', avatar: '' },
roomConfig: { maxRounds: 5 }
})
// 4. 成员加入房间
await game.joinRoom({
roomId: 'room-xxx',
playerInfo: { name: '玩家2' }
})
// 5. 监听玩家加入 / 离开
game.on('peer-join', e => console.log('玩家加入', e.peerId))
game.on('peer-leave', e => console.log('玩家离开', e.peerId))
// 6. 广播消息(仅房主)
await game.getMultiplayerManager().broadcast('custom-event', { foo: 'bar' })
// 7. 销毁
await game.dispose()
使用指南
1. 状态机
内置通用状态:idle / ready / loading / playing / paused / round-start / round-end / intermission / waiting / game-over / error。
import { GAME_STATE } from '@/uni_modules/jz-gameManager'
// 监听
game.on('state-change', ({ prev, next, ts }) => {
console.log(`${prev} -> ${next} @ ${ts}`)
})
// 跳转
game.setState(GAME_STATE.PLAYING)
// 查询
game.getState() // 当前状态
game.getPreviousState() // 上一个状态
game.canTransitionTo(GAME_STATE.GAME_OVER) // 是否可跳转
自定义状态与跳转规则
const game = await createGameManager({
gameId: 'rpg',
initialState: 'menu',
stateTransitions: {
menu: ['battle', 'shop'],
battle: ['menu', 'game-over'],
shop: ['menu'],
'game-over': ['menu']
}
})
2. 模式管理
import { GAME_MODE } from '@/uni_modules/jz-gameManager'
game.setMode(GAME_MODE.VERSUS)
game.getMode() // 当前模式
game.getModeManager().supports('realtimeSync') // 模式特性查询
支持的模式:SINGLE / MULTIPLAYER / VERSUS / COOPERATIVE,每种模式预置 realtimeSync / roomManagement / playerDataSync / voiceChat / hostAuthoritative 等能力开关。
3. 计时器
// 倒计时
const id = game.startCountdown({
duration: 30, // 秒
tickInterval: 1, // 触发频率
onTick: (remaining, elapsed) => {},
onEnd: () => {}
})
// 正计时
game.startCountup({
maxDuration: 300,
onTick: elapsed => {}
})
// 回合计时
game.startRoundTimer({
rounds: 5,
roundDuration: 60,
onRoundStart: round => {},
onRoundEnd: round => {},
onAllRoundsEnd: () => {}
})
// 间隔触发
game.startInterval({
interval: 2,
onTick: count => {}
})
// 控制
game.stopTimer(id)
game.pauseAllTimers()
game.resumeAllTimers()
game.stopAllTimers()
4. 数据管理
| 维度 | 方法 | 说明 |
|---|---|---|
| 运行时(内存) | setData / getData / removeData / clearData |
速度最快,重启丢失 |
| 本地持久化 | setLocalData / getLocalData |
落地到 uni.setStorage |
| 多槽位存档 | getDataManager().saveProgress(progress) / loadProgress(slotId) |
适合关卡进度 |
| 房间数据 | getDataManager().setRoomData / getRoomData |
房主写入并广播给成员 |
| 玩家数据 | getDataManager().setPlayerData(peerId, key, value) |
各成员独立数据 |
game.setLocalData('coin', 1000)
game.setData('runtime.combo', 3)
game.on('data-change', e => console.log(e.scope, e.key, e.value))
// 自动保存
game.getDataManager().startAutoSave(5000) // 5s 持久化一次
// 导入 / 导出
const snapshot = game.getDataManager().exportData()
game.getDataManager().importData(snapshot)
5. 音效 / 音乐 / 朗读
// 在 createGameManager() 时预注册资源别名
sounds: { click: '/static/click.mp3', win: '/static/win.mp3' },
music: { bgm: '/static/bgm.mp3' }
// 音效
const playId = game.playSound('click', { volume: 0.8, loop: false })
game.stopSound(playId)
game.stopAllSounds()
// 背景音乐(自动渐入 / 切换)
game.playBGM('bgm', { fadeIn: 800, loop: true })
game.pauseBGM()
game.resumeBGM()
game.switchBGM('/static/boss.mp3', { fadeOut: 500, fadeIn: 500 })
game.stopBGM()
// 文字朗读(Web Speech API)
game.speakText('恭喜你获胜', { rate: 1, pitch: 1, lang: 'zh-CN' })
game.stopAllSpeaking()
6. 随机数生成
const rng = game.getRandomGenerator()
rng.setSeed(20260624) // 设定种子
rng.randomWithSeed() // 可复现序列
rng.randint(1, 100) // [1, 100]
rng.randfloat(0, 1) // [0, 1)
rng.choice(['rock', 'paper', 'scissors'])
rng.shuffle([1, 2, 3, 4, 5]) // 洗牌
rng.byProbability(0.3) // 30% 命中
rng.byWeight([['SSR', 1], ['SR', 9], ['R', 90]]) // 权重抽取
7. 分数管理
const score = game.getScoreManager()
score.registerPlayer('p1', { name: '玩家1' })
score.registerPlayer('p2', { name: '玩家2' })
score.addScore(10, 'p1')
score.addScore(-5, 'p2')
score.setScore('p1', 100)
score.getScore('p1')
const top = score.getLeaderboard() // 排行榜
const high = score.getHighScore() // 历史最高
8. 帧动画
import { FrameAnimationPlayer, FRAME_LOOP_MODE } from '@/uni_modules/jz-gameManager'
// 1) 按目录加载序列帧
const node = FrameAnimationPlayer.fromFramesByDir({
dir: '/static/anim/run',
count: 8,
ext: 'png',
fps: 12,
loop: FRAME_LOOP_MODE.LOOP
})
// 2) 雪碧图
const node2 = FrameAnimationPlayer.fromSpriteSheet({
src: '/static/sheet.png',
frameWidth: 64,
frameHeight: 64,
count: 10,
fps: 24,
loop: FRAME_LOOP_MODE.PINGPONG
})
// 3) 多动画集合
const hero = FrameAnimationPlayer.fromAnimations({
defaultAnimation: 'idle',
animations: {
idle: { frames: [/* ... */], fps: 8 },
run: { frames: [/* ... */], fps: 12 },
attack: { frames: [/* ... */], fps: 16, loop: false }
}
})
hero.play()
hero.switchAnimation('run')
hero.update(deltaMs) // 在 requestAnimationFrame 循环中调用
hero.getCurrentSrc() // 取当前帧资源
9. 多人联机
多人联机走 依赖注入 模式:你需要自行实现 ConnectProvider 接口,再传给 GameManager。
9.1 实现 ConnectProvider
ConnectProvider 定义了一组与传输层无关的契约:
import { ConnectProvider } from '@/uni_modules/jz-gameManager'
class MyAdapter extends ConnectProvider {
async init(options) // 初始化,返回 peerId
async send(peerId, channel, data, options) // 点对点发送
async broadcast(channel, data, options) // 广播(host)
async request(peerId, channel, data, options) // 请求-响应
async kick(peerId, reason) // 踢人(host)
getPeerId()
getPeers()
on(event, handler) // ready / peer-join / peer-leave / message / request / error
off(event, handler)
async dispose()
}
完整可工作的参考实现:
src/pages/game/rps/composables/RpsConnectAdapter.js,基于jz-webrtc-connect包装。
9.2 注入到 GameManager
const adapter = new MyAdapter(coreInstance)
const game = await createGameManager({
gameId: 'rps',
mode: GAME_MODE.MULTIPLAYER,
adapter,
multiplayer: {
maxPlayers: 2,
minPlayersToStart: 2,
syncRoomData: true
}
})
9.3 房间与消息
// 房主
await game.createRoom({ playerInfo: { name: 'Host' }, roomConfig: { rounds: 3 } })
// 成员
await game.joinRoom({ roomId, playerInfo: { name: 'Guest' } })
// 查询
game.getRoomInfo()
game.getPlayers()
const mp = game.getMultiplayerManager()
// 自定义消息
mp.registerMessageHandler('action', ({ from, payload }) => {})
await mp.broadcast('action', { type: 'jump' })
await mp.sendTo(peerId, 'action', { type: 'attack' })
await mp.sendToHost('action', { type: 'ready' })
// 离开
await game.leaveRoom()
API 总览
入口(顶层导出)
import {
createGameManager, // 创建并初始化单例
getGameManager, // 获取已创建的单例
destroyGameManager, // 销毁单例
configure, // 配置全局默认选项(create 前调用)
getConfig,
// 类
GameManager, GameStateMachine, GameModeManager, GameTimerManager,
GameDataManager, MultiplayerManager,
ConnectProvider,
GameStoreBase, PlayerStore, RoomStore, ProgressStore,
MemoryDriver, UniStorageDriver,
SoundPlayer, MusicPlayer, TextReader,
RandomGenerator, GameScoreManager, FrameAnimationPlayer,
EventBus, GameError,
// 常量
GAME_STATE, DEFAULT_STATE_TRANSITIONS,
GAME_MODE, MODE_FEATURES,
MULTIPLAYER_STATE, PLAYER_STATE, PLAYER_ROLE,
GAME_MESSAGE_TYPE, TIMER_TYPE,
FRAME_LOOP_MODE,
ERROR_CODES, VERSION
} from '@/uni_modules/jz-gameManager'
GameManager(门面)
| 分类 | 方法 |
|---|---|
| 生命周期 | createGameManager(options) / getGameManager() / destroyGameManager() / dispose() |
| 状态机 | setState(state, options) / getState() / getPreviousState() / canTransitionTo(state) / getStateMachine() |
| 模式 | setMode(mode, config) / getMode() / getModeManager() |
| 多人联机 | createRoom(opts) / joinRoom(opts) / leaveRoom() / getRoomInfo() / getPlayers() / getMultiplayerManager() |
| 数据 | setLocalData(k,v) / getLocalData(k) / setData(k,v) / getData(k) / saveData() / loadData() / hasData(k) / removeData(k) / clearData() / getDataManager() |
| 音效 | playSound(name, opts) / stopSound(id) / stopAllSounds() / getSoundPlayer() |
| 音乐 | playBGM / stopBGM / pauseBGM / resumeBGM / switchBGM 及别名 playMusic / stopMusic / pauseMusic / resumeMusic / switchMusic,getMusicPlayer() |
| 朗读 | speakText(text, opts) / stopSpeaking(id) / stopAllSpeaking() 及别名 speak / stopSpeak / stopAllSpeak,getTextReader() |
| 计时器 | startCountdown / startCountup / startRoundTimer / startInterval / stopTimer(id) / stopAllTimers / pauseAllTimers / resumeAllTimers / getTimerManager() |
| 工具 | getRandomGenerator() / getScoreManager() |
| 事件 | on(event, handler) / off(event, handler) / once(event, handler) |
事件
通过 GameManager.on(event, handler) 统一订阅:
| 事件 | 触发时机 |
|---|---|
init |
初始化完成 |
state-change |
游戏状态变更 |
mode-change |
游戏模式变更 |
data-change |
任意数据域(local / memory / room / player)发生变更 |
room-created / room-joined |
房间创建 / 加入成功 |
peer-join / peer-leave |
玩家加入 / 离开 |
message |
收到多人消息 |
sync |
状态同步 |
disconnect / reconnect |
网络断开 / 重连 |
error |
发生错误(含 GameError 实例) |
枚举常量
GAME_STATE:游戏状态DEFAULT_STATE_TRANSITIONS:默认状态跳转规则GAME_MODE/MODE_FEATURES:游戏模式与特性矩阵MULTIPLAYER_STATE:联机状态PLAYER_STATE/PLAYER_ROLE:玩家状态与角色GAME_MESSAGE_TYPE:多人消息类型TIMER_TYPE:计时器类型FRAME_LOOP_MODE:帧动画循环模式(ONCE / LOOP / PINGPONG)ERROR_CODES:错误码VERSION:插件版本号(1.0.0)
平台支持
| 平台 | 单机功能 | 多人联机 |
|---|---|---|
| H5 (Chrome / Safari) | √ | √ |
| App (Vue / nvue) | √ | × |
| 小程序 | √ | × |
多人联机依赖 WebRTC,仅 H5 可用;其余能力(状态机、计时器、数据、音效、随机数、分数、帧动画)全平台可用。
演示页面
工程内置 7 个 Demo 页面,覆盖全部核心能力,可直接运行查看效果:
| 路径 | 内容 |
|---|---|
/pages/index/index |
插件首页与功能总览 |
/pages/game/basic/index |
基础功能:状态机 + 音效 + 音乐 + 计时器 |
/pages/game/score/index |
分数管理:多玩家分数 + 排行榜 |
/pages/game/random/index |
随机数:种子 / 概率 / 权重 / 洗牌 |
/pages/game/timer/index |
计时器:倒计时 / 正计时 / 回合 / 间隔 |
/pages/game/data/index |
数据存储:本地持久化 + 运行时 + 监听 |
/pages/game/animation/index |
帧动画:序列帧 / 雪碧图 / 多动画 / 乒乓 |
/pages/game/rps/lobby/index |
剪刀石头布:多人联机 + 三局两胜的综合示例 |

收藏人数:
下载插件并导入HBuilderX
下载插件ZIP
赞赏(0)
下载 2436
赞赏 0
下载 12322909
赞赏 1923
赞赏
京公网安备:11010802035340号