/** * ============================================================================ * 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; }