初始化仓库:友乐/gameabc 房卡游戏平台脚手架(client + server + docs)

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-07-01 18:13:26 +08:00
co-authored by Claude Opus 5
commit 594820d393
655 changed files with 310861 additions and 0 deletions
@@ -0,0 +1,196 @@
/**
* ============================================================================
* UIBootstrap.template.js - UI 启动器规范模板
* ============================================================================
*
* 使用方式:
* 将此文件复制到游戏目录,重命名为 UIBootstrap.js。
* 根据游戏实际使用的 UI 组件修改 _registerViews() 和 _checkDependencies()。
*
* 加载顺序(index.html 中必须按序):
* 1. gameabc-framework/core/EventBus.js
* 2. gameabc-framework/core/SpriteManager.js
* 3. gameabc-framework/ui/BaseComponent.js
* 4. gameabc-framework/ui/UIManager.js ← 框架层
* 5. game/ui/UIManager.js ← 游戏层扩展(如 CreateRoomUI)
* 6. game/ui/views/RoomView.js ← 各视图组件
* 7. game/ui/views/GameView.js
* 8. game/UIBootstrap.js ← 本文件(最后加载)
*
* 调用时机:
* 在 Logic.AppStart() 中调用 UIBootstrap.init()
*
* ============================================================================
* @guide UIBootstrap 的职责
* ============================================================================
*
* UIBootstrap 是游戏专属的启动器,负责:
* 1. 按序初始化框架系统(SpriteManager → AnimationManager → UIManager)
* 2. 创建游戏专属视图组件
* 3. 向 UIManager 注册组件和场景
* 4. 提供 views 字典供全局访问
*
* UIBootstrap 不应该:
* - 包含业务逻辑(发牌、胡牌判断等)
* - 直接操作精灵(应交给各 View 组件)
* - 被其他模块 require(单向依赖)
*
* ============================================================================
* @guide 场景注册示例
* ============================================================================
*
* // 在 _registerViews() 中,创建并注册完所有组件后:
*
* // 1. 注册到 UIManager 组件表
* UIManager.registerComponent('RoomView', this.views.RoomView);
* UIManager.registerComponent('GameView', this.views.GameView);
*
* // 2. 注册场景(组件名称必须已注册)
* UIManager.registerScene(UIManager.SCENES.ROOM, ['RoomView']);
* UIManager.registerScene(UIManager.SCENES.GAME, ['GameView', 'JingCardView', 'DiceView']);
*
* @see UIManager.js 框架层组件/场景管理(gameabc-framework/ui/)
* @see BaseComponent.js 组件基类(gameabc-framework/ui/)
*/
var UIBootstrap = UIBootstrap || {};
// ============================================================================
// 状态
// ============================================================================
UIBootstrap.initialized = false;
/** 游戏创建的所有 View 实例 */
UIBootstrap.views = {};
// ============================================================================
// 公共 API
// ============================================================================
/**
* 初始化 UI 系统
* 在 Logic.AppStart() 中调用一次
* @returns {boolean}
*/
UIBootstrap.init = function () {
if (this.initialized) {
console.warn('[UIBootstrap] 已初始化,跳过');
return true;
}
console.log('[UIBootstrap] 开始初始化 UI 系统...');
try {
if (!this._checkDependencies()) { return false; }
// 1. 初始化 SpriteManager
SpriteManager.init();
// 2. 初始化 AnimationManager(如有)
if (typeof AnimationManager !== 'undefined') {
AnimationManager.init();
}
// 3. 初始化 UIManager(框架层 + 游戏扩展)
// 如有 Loading/Message/Confirm 全局 UI,注入各自精灵常量(框架不读子游戏全局名):
// UIManager.init({ loadingUI: SpriteConstants.LOADING_UI, messageUI: SpriteConstants.MESSAGE_UI, confirmUI: SpriteConstants.CONFIRM_UI });
// 无全局 UI 则直接 UIManager.init();
UIManager.init();
// 4. 创建并注册所有视图
this._registerViews();
this.initialized = true;
console.log('[UIBootstrap] UI 系统初始化完成,共', Object.keys(this.views).length, '个组件');
return true;
} catch (err) {
console.error('[UIBootstrap] 初始化失败:', err);
return false;
}
};
/**
* 检查依赖是否已加载
* ⚠️ 按游戏实际使用的组件修改此列表
* @private
*/
UIBootstrap._checkDependencies = function () {
var required = [
{ name: 'EventBus', ok: typeof EventBus !== 'undefined' },
{ name: 'SpriteManager', ok: typeof SpriteManager !== 'undefined' },
{ name: 'UIManager', ok: typeof UIManager !== 'undefined' },
{ name: 'RoomView', ok: typeof RoomView !== 'undefined' },
{ name: 'GameView', ok: typeof GameView !== 'undefined' }
];
var optional = [
// { name: 'JingCardView', ok: typeof JingCardView !== 'undefined' },
// { name: 'DiceView', ok: typeof DiceView !== 'undefined' }
];
var allOk = true;
for (var i = 0; i < required.length; i++) {
if (!required[i].ok) {
console.error('[UIBootstrap] 缺少依赖:', required[i].name);
allOk = false;
}
}
for (var j = 0; j < optional.length; j++) {
if (!optional[j].ok) {
console.warn('[UIBootstrap] 可选组件未加载:', optional[j].name);
}
}
return allOk;
};
/**
* 创建视图实例并注册到 UIManager
* ⚠️ 按游戏实际使用的组件修改此方法
* @private
*/
UIBootstrap._registerViews = function () {
// ---- 创建组件 ----
this.views.RoomView = RoomView.create({ name: 'RoomView' });
this.views.GameView = GameView.create({ name: 'GameView' });
// this.views.JingCardView = JingCardView.create({ name: 'JingCardView' });
// this.views.DiceView = DiceView.create({ name: 'DiceView' });
// ---- 注册到 UIManager ----
UIManager.registerComponent('RoomView', this.views.RoomView);
UIManager.registerComponent('GameView', this.views.GameView);
// ---- 注册场景 ----
UIManager.registerScene(UIManager.SCENES.ROOM, ['RoomView']);
UIManager.registerScene(UIManager.SCENES.GAME, ['GameView']);
};
// ============================================================================
// 工具方法
// ============================================================================
UIBootstrap.getView = function (viewName) {
return this.views[viewName] || null;
};
UIBootstrap.showView = function (viewName) {
if (!this.initialized) { return; }
UIManager.showView(viewName);
};
UIBootstrap.hideView = function (viewName) {
if (!this.initialized) { return; }
UIManager.hideView(viewName);
};
UIBootstrap.getStatus = function () {
return {
initialized: this.initialized,
views: Object.keys(this.views),
uiManagerReady: UIManager.initialized
};
};
if (typeof module !== 'undefined' && module.exports) {
module.exports = UIBootstrap;
}