// ============================================================================ // 01_SubGame_modify.js —— 平台交互/创建房间接口「转发壳」(框架维护,子游戏不碰) // 顶部为「房型/创建房间配置区」(数据,子游戏填值);其下为接口转发壳(转发到 SubGameHooks)。 // 严格 ES5。 // ---------------------------------------------------------------------------- // 【平台约定精灵:25 号 = 创建房间确认按钮】(接入子游戏必看) // 平台框架在「创建房间」界面提供 25 号精灵作为“确认/提交”按钮;其点击交互与 // 发送的数据包,均需【子游戏自己实现】(平台不代发),约定流程: // 1. 子游戏在打开创建房间界面时注册 25 号精灵的点击(经 SpriteEventController // 或 mouseup),点击即“确认创建房间”。 // 2. 子游戏按界面选项拼出 roomtype(房型配置串,编码局数/人数/扣卡/规则等, // 由各子游戏按玩法自定义与解析),组装并发送创建房间请求: // Net.Send_create_room({ // agentid : GameData.AgentId, // playerid: C_Player.playerid, // gameid : GameData.GameId, // roomtype: <房型配置字符串> // }); // // 本麻将实现见 codes/game/ui/handlers/CreateRoomEventHandler(bindEvents 注册 // 25→submit;submit 用 UIManager._buildRoomTypeString 拼 roomtype 后 Net.Send_create_room)。 // ============================================================================ // ---------- 配置区(数据,子游戏按玩法填值;与 00 的 Game_Config 分工) ---------- var Game_Modify = Game_Modify || {}; // ---------- 平台需要的必须字段 ---------- Game_Modify.roomDes = ""; // 房间描述,子游戏在 setRoomDes 内填 Game_Modify.game_config = {}; // 游戏配置默认值 Game_Modify.combat = { maxPlayerCount: 5, pageOnelimitStrLen: 8, pageOneDoc: false, pageTwolimitStrLen: 16, pageTwoDoc: false }; Game_Modify.Type_1 = [ { id: 0, des: "10局(房卡X1)", roomcard: 1, type: 1 }, { id: 1, des: "20局(房卡X2)", roomcard: 2, type: 2 } ]; Game_Modify.Type_2 = [ { id: 0, des: "房主扣卡", type: 1 }, { id: 1, des: "每人扣卡", type: 2 } ]; Game_Modify.CreateRoomData = { Type_1: 0, Type_2: 0 }; // ---------- 玩家信息/头像默认布局(供 02 转发壳 updatePlayerInfoUI 的默认实现使用)---------- // 02_SubGame_Input.js 的 updatePlayerInfoUI 在【无 SubGameHooks 实现】时提供默认头像等 UI 渲染; // 转发壳不得引用 codes,故把默认实现所需布局放在此处(Game_Modify 下),与子游戏 codes 内 // GameView.updatePlayerInfoUI 使用的布局逻辑保持一致。子游戏若自定义头像 UI,则用 hook 覆盖、此配置不生效。 // POSITIONS[configIndex]:ind0=南(自己)/ind1=东/ind2=北/ind3=西;渲染精灵 346+ind 底框、376+ind 头像框、 // 406+ind 昵称、436+ind 分数、116+ind 头像图、群组 43+ind。坐标基于设计分辨率 1280x720。 Game_Modify.PLAYER_INFO_LAYOUT = { POSITIONS: { 0: { FRAME_X: 6, FRAME_Y: 592, FRAME_WIDTH: 90, FRAME_HEIGHT: 115, AVATAR: { OFFSET_X: 5, OFFSET_Y: 5, WIDTH: 80, HEIGHT: 80, NAME_OFFSET_X: -400, NAME_OFFSET_Y: 888, SCORE_OFFSET_X: 0, SCORE_OFFSET_Y: 88 }, NAME_CENTER_ALIGN: true }, 1: { FRAME_X: 1186, FRAME_Y: 85, FRAME_WIDTH: 90, FRAME_HEIGHT: 115, AVATAR: { OFFSET_X: 5, OFFSET_Y: 5, WIDTH: 80, HEIGHT: 80, NAME_OFFSET_X: 905, NAME_OFFSET_Y: -888, SCORE_OFFSET_X: 0, SCORE_OFFSET_Y: 88 }, NAME_CENTER_ALIGN: true }, 2: { FRAME_X: 1006, FRAME_Y: 5, FRAME_WIDTH: 90, FRAME_HEIGHT: 115, AVATAR: { OFFSET_X: 5, OFFSET_Y: 5, WIDTH: 80, HEIGHT: 80, NAME_OFFSET_X: 905, NAME_OFFSET_Y: -888, SCORE_OFFSET_X: 0, SCORE_OFFSET_Y: 88 }, NAME_CENTER_ALIGN: true }, 3: { FRAME_X: 7, FRAME_Y: 59, FRAME_WIDTH: 90, FRAME_HEIGHT: 115, AVATAR: { OFFSET_X: 5, OFFSET_Y: 5, WIDTH: 80, HEIGHT: 80, NAME_OFFSET_X: -605, NAME_OFFSET_Y: -888, SCORE_OFFSET_X: 0, SCORE_OFFSET_Y: 88 }, NAME_CENTER_ALIGN: true } }, TEXT_STYLE: { NAME_FONT_SIZE: 14, NAME_MAX_LENGTH: 6, SCORE_FONT_SIZE: 12, CHAR_WIDTH: 9 } }; // ---------- 桌面聊天/语音气泡默认布局(供 02 转发壳 ShowChat/gameui_play_voice/gameui_stop_voice 使用)---------- // 平台默认按固定显示位序取 Game_Config.Chat/Voice 的固定坐标(固定人数模式);此处提供可变人数版: // 按 updatePlayerInfoUI 的 configIndex(物理位) 定位,使气泡随人数(2/3/4)贴合各玩家。 // 仅定义每个物理位(0南/1东/2北/3西)的气泡框左上角锚点 X/Y 与朝向 IS_LEFT;气泡内边距/字宽/显示时长等 // 尺寸复用平台 Game_Config.Chat/Voice/Max(与人数无关)。精灵:聊天 背景552+ind/文字582+ind, // 语音 背景612+ind/内容642+ind。IS_LEFT=true 气泡向右展开(用 IMG_LEFT)、false 向左展开(用 IMG_RIGHT)。 // 坐标基于 1280x720,锚点参考 PLAYER_INFO_LAYOUT 各位底框,可按实际界面微调。 Game_Modify.BUBBLE_LAYOUT = { IMG_LEFT: 83, // 左向气泡背景图资源ID(气泡向右展开) IMG_RIGHT: 86, // 右向气泡背景图资源ID(气泡向左展开) POSITIONS: { 0: { X: 100, Y: 540, IS_LEFT: true }, // 南(自己) 1: { X: 1176, Y: 120, IS_LEFT: false }, // 东 2: { X: 970, Y: 20, IS_LEFT: false }, // 北 3: { X: 120, Y: 70, IS_LEFT: true } // 西 } }; // ---------- 接口转发壳(A 类:无 hook 即 no-op) ---------- Game_Modify.utlmousedown = function (gameid, spid, downx, downy, no1, no2, no3, no4, no5, no6) { if (window.SubGameHooks && SubGameHooks.utlmousedown) return SubGameHooks.utlmousedown(gameid, spid, downx, downy, no1, no2, no3, no4, no5, no6); }; Game_Modify.utlmousedown_nomove = function (gameid, spid, downx, downy, timelong, no1, no2, no3, no4, no5) { if (window.SubGameHooks && SubGameHooks.utlmousedown_nomove) return SubGameHooks.utlmousedown_nomove(gameid, spid, downx, downy, timelong, no1, no2, no3, no4, no5); }; Game_Modify.mouseup = function (gameid, spid_down, downx, downy, spid_up, upx, upy, timelong, no1, no2) { if (window.SubGameHooks && SubGameHooks.mouseup) return SubGameHooks.mouseup(gameid, spid_down, downx, downy, spid_up, upx, upy, timelong, no1, no2); }; Game_Modify.utlmousemove = function (gameid, spid, downx, downy, movex, movey, timelong, offmovex, offmovey, no1) { if (window.SubGameHooks && SubGameHooks.utlmousemove) return SubGameHooks.utlmousemove(gameid, spid, downx, downy, movex, movey, timelong, offmovex, offmovey, no1); }; Game_Modify.utlgamemydrawbegin = function (gameid, spid, times, timelong, no2, no3, no4, no5, no6, no7) { if (window.SubGameHooks && SubGameHooks.utlgamemydrawbegin) return SubGameHooks.utlgamemydrawbegin(gameid, spid, times, timelong, no2, no3, no4, no5, no6, no7); }; Game_Modify.gamemydraw = function (gameid, spid, times, timelong, no2, no3, no4, no5, no6, no7) { if (window.SubGameHooks && SubGameHooks.gamemydraw) return SubGameHooks.gamemydraw(gameid, spid, times, timelong, no2, no3, no4, no5, no6, no7); }; Game_Modify.OpenCreateRoom = function () { if (window.SubGameHooks && SubGameHooks.OpenCreateRoom) return SubGameHooks.OpenCreateRoom(); }; Game_Modify.CloseCreateRoom = function () { if (window.SubGameHooks && SubGameHooks.CloseCreateRoom) return SubGameHooks.CloseCreateRoom(); }; Game_Modify.setRoomDes = function (roomcode, asetcount, roomtype) { if (window.SubGameHooks && SubGameHooks.setRoomDes) return SubGameHooks.setRoomDes(roomcode, asetcount, roomtype); }; // ---------- gameCombat 兼容空定义 ---------- // 平台 gamemain.js 仍直接调用 gameCombat.utl*(战绩界面回调),保留全局对象与 6 个空接口防报错。 // 战绩功能由 RecordView 重建(见迁移子项目 2);届时这些接口可改为委托或保持空。 var gameCombat = gameCombat || {}; gameCombat.utlani_doend = gameCombat.utlani_doend || function () {}; gameCombat.utlmousedown = gameCombat.utlmousedown || function () {}; gameCombat.utlmouseup = gameCombat.utlmouseup || function () {}; gameCombat.utlmousemove = gameCombat.utlmousemove || function () {}; gameCombat.utlgamemydraw = gameCombat.utlgamemydraw || function () {}; gameCombat.utlgamemydrawbegin = gameCombat.utlgamemydrawbegin || function () {}; // 战绩接收入口(平台 09_Net 调):转发到 SubGameHooks(框架转发壳不引用 codes;子游戏在 SubGameHooks 内转 CombatService) gameCombat.get_player_grade1 = function (_msg) { if (window.SubGameHooks && SubGameHooks.get_player_grade1) return SubGameHooks.get_player_grade1(_msg); }; gameCombat.get_player_grade2 = function (_msg) { if (window.SubGameHooks && SubGameHooks.get_player_grade2) return SubGameHooks.get_player_grade2(_msg); }; // 战绩入口:13 号精灵点击 → 发送获取战绩请求(Net.Send_get_player_grade1,平台底层发送) // 点击经 平台 → Game_Modify.mouseup → SubGameHooks.mouseup → SpriteEventController 链到达 if (typeof SpriteEventController !== 'undefined' && SpriteEventController.registerMouseUp) { SpriteEventController.registerMouseUp(13, function () { if (typeof Net !== 'undefined' && Net.Send_get_player_grade1) { Net.Send_get_player_grade1({ agentid: GameData.AgentId, playerid: C_Player.playerid, gameid: GameData.GameId, type: 0 }); } }); } // 平台通用精灵交互(从 SubGameHooks 移入;经 Game_Modify.mouseup/gamemydraw→SubGameHooks→SpriteEventController 分发) // 注:25 号(创建房间提交)已归创建房间职责,移至 codes/game/ui/handlers/CreateRoomEventHandler.bindEvents。 if (typeof SpriteEventController !== 'undefined') { // 150:帮助按钮 if (SpriteEventController.registerMouseUp) { SpriteEventController.registerMouseUp(150, function () { if (typeof GameUI !== 'undefined' && GameUI.OpenHelp) { GameUI.OpenHelp(); } }); } // 248:协议勾选绘制(勾上时自绘钩) if (SpriteEventController.registerDraw) { SpriteEventController.registerDraw(248, function (e) { if (GameData.ProtocolIndex) { ifast_mydrawbmp(e.spriteId, 4, 5, 5, 40, 40, 0, 0, 40, 40); } }); } }