规则文档理清楚,开始代码层面对比和校对
This commit is contained in:
@@ -911,7 +911,7 @@ Desk.send_text=function(_msg){//发送消息
|
||||
if(!_msg.data.type){
|
||||
var pobj = Desk.GetPlayerBySeat(_msg.data.seat);
|
||||
GameUI.playTextVoice(_msg.data.text,pobj.sex);
|
||||
GameUI.ShowChat(Logic.ChangeToStatus(C_Player.seat,_msg.data.seat),_msg.data.text);
|
||||
GameUI.ShowChat(_msg.data.seat,_msg.data.text);
|
||||
GameUI.addCommunion(Logic.ChangeToStatus(C_Player.seat,_msg.data.seat),1,_msg.data.text,0,null,pobj.sex);
|
||||
}else if(_msg.data.type == 1){//全服公告
|
||||
GameUI.CloseChat();
|
||||
@@ -929,7 +929,7 @@ Desk.send_text=function(_msg){//发送消息
|
||||
var idx = Number(_msg.data.text);
|
||||
_msg.data.text = Game_Config.Info.TextContent[(idx - 1)%Game_Config.Info.TextContent.length];
|
||||
GameUI.playTextVoice(_msg.data.text);
|
||||
GameUI.ShowChat(Logic.ChangeToStatus(C_Player.seat,_msg.data.seat),_msg.data.text);
|
||||
GameUI.ShowChat(_msg.data.seat,_msg.data.text);
|
||||
GameUI.addCommunion(Logic.ChangeToStatus(C_Player.seat,_msg.data.seat),1,_msg.data.text,0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5779,7 +5779,12 @@ GameUI.ShowEmotion = function(v, ind) {
|
||||
|
||||
}
|
||||
|
||||
GameUI.ShowChat = function(v, text) {
|
||||
GameUI.ShowChat = function(seat, text) {
|
||||
if (Game_Modify.ShowChat) {
|
||||
Game_Modify.ShowChat(seat, text);
|
||||
return;
|
||||
}
|
||||
var v = Logic.ChangeToStatus(C_Player.seat,seat);
|
||||
text = String(text);
|
||||
set_self(204, 7, "", 0, 0);
|
||||
if (v == 0) {
|
||||
@@ -6085,6 +6090,7 @@ GameUI.play_voice = function(_msg, type, v) {
|
||||
|
||||
function gameui_play_voice(v) {
|
||||
v = Number(v);
|
||||
|
||||
var bTemp = false;
|
||||
if (v >= ConstVal.Com_History.content_tag) {
|
||||
bTemp = true;
|
||||
@@ -6092,6 +6098,10 @@ function gameui_play_voice(v) {
|
||||
if (bTemp) {
|
||||
play_ani(1, ConstVal.Com_History.f_spid + "add" + v, 43, 1, 3, 0, 600, 0, 0, 0, 0, 0, 0);
|
||||
} else {
|
||||
if(Game_Modify.gameui_play_voice){
|
||||
Game_Modify.gameui_play_voice(v);
|
||||
return;
|
||||
}
|
||||
var x = Game_Config.Voice.VoiceLoc[v][0];
|
||||
var y = Game_Config.Voice.VoiceLoc[v][1];
|
||||
var dis_x = Game_Config.Voice.VoiceDis[0];
|
||||
@@ -6128,10 +6138,15 @@ function gameui_stop_voice(v) {
|
||||
if (v >= ConstVal.Com_History.content_tag) {
|
||||
bTemp = true;
|
||||
}
|
||||
|
||||
if (bTemp) {
|
||||
play_ani(0, ConstVal.Com_History.f_spid + "add" + v, 43, 1, 3, 0, 600, 0, 0, 0, 0, 0, 0);
|
||||
set_self(ConstVal.Com_History.f_spid + "add" + v, 43, 3, 0, 0);
|
||||
} else {
|
||||
if(Game_Modify.gameui_stop_voice){
|
||||
Game_Modify.gameui_stop_voice(v);
|
||||
return;
|
||||
}
|
||||
set_self(612 + v, 37, 0, 0, 0);
|
||||
set_self(642 + v, 37, 0, 0, 0);
|
||||
play_ani(0, 642 + v, 43);
|
||||
|
||||
@@ -46,6 +46,52 @@ Game_Modify.CreateRoomData = {
|
||||
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) {
|
||||
|
||||
@@ -293,8 +293,210 @@ Game_Modify.getMaxPlayerCount = function (roomtype) {
|
||||
return (Game_Config.Max && Game_Config.Max.PlayerCnt) || 4;
|
||||
};
|
||||
|
||||
// B 类:更新玩家信息 UI,无 hook 返回 false(让平台默认处理)
|
||||
// 内部辅助(非平台接口):把相对显示位序 relPos 映射为 { ind:精灵槽, configIndex:物理布局位 }。
|
||||
// 2/3 人时 ind≠configIndex;无效返回 null。updatePlayerInfoUI 与桌面气泡默认实现共用此映射,
|
||||
// 保证头像面板与聊天/语音气泡落在同一玩家位。
|
||||
Game_Modify._resolveDisplaySlot = function (relPos, playerCount) {
|
||||
var ind = -1, configIndex = -1;
|
||||
if (playerCount === 2) {
|
||||
if (relPos === 0) { ind = 0; configIndex = 0; }
|
||||
else if (relPos === 1) { ind = 1; configIndex = 2; }
|
||||
} else if (playerCount === 3) {
|
||||
if (relPos === 0) { ind = 0; configIndex = 0; }
|
||||
else if (relPos === 1) { ind = 1; configIndex = 1; }
|
||||
else if (relPos === 2) { ind = 2; configIndex = 3; }
|
||||
} else {
|
||||
if (relPos === 0) { ind = 0; configIndex = 0; }
|
||||
else if (relPos === 1) { ind = 1; configIndex = 1; }
|
||||
else if (relPos === 2) { ind = 2; configIndex = 2; }
|
||||
else if (relPos === 3) { ind = 3; configIndex = 3; }
|
||||
}
|
||||
if (ind === -1) return null;
|
||||
return { ind: ind, configIndex: configIndex };
|
||||
};
|
||||
|
||||
// B 类:更新指定座位的玩家信息 UI(昵称/分数/头像)。
|
||||
// 有 hook 则委托子游戏;无 hook 时由本模板提供默认头像等 UI 的显示逻辑,其逻辑与子游戏
|
||||
// codes 内 GameView.updatePlayerInfoUI 保持一致,布局取自 Game_Modify.PLAYER_INFO_LAYOUT(见 01)。
|
||||
// 精灵操作一律经框架 SpriteManager(setPosition/setSize/setText/show|hideGroup),不直接调
|
||||
// set_self/set_group 等引擎原语;头像加载走平台 Func.up_imgurl(非精灵原语,SpriteManager 无对应能力)。
|
||||
// 不引用任何 codes 模块。平台 GameUI.updatePlayerInfoUI 会对每个座位逐一调用本接口,故按单座位渲染。
|
||||
Game_Modify.updatePlayerInfoUI = function (targetSeat) {
|
||||
if (window.SubGameHooks && SubGameHooks.updatePlayerInfoUI) return SubGameHooks.updatePlayerInfoUI(targetSeat);
|
||||
return false;
|
||||
|
||||
// ---- 模板默认:与 GameView.updatePlayerInfoUI 一致的单座位渲染 ----
|
||||
if (typeof Desk === 'undefined' || typeof C_Player === 'undefined' || typeof SpriteManager === 'undefined') return false;
|
||||
var layout = Game_Modify.PLAYER_INFO_LAYOUT;
|
||||
if (!layout || !layout.POSITIONS) return false;
|
||||
if (!Desk.PlayerList || targetSeat < 0 || targetSeat >= Desk.PlayerList.length) return false;
|
||||
|
||||
var selfSeat = (typeof C_Player.seat === 'number') ? C_Player.seat : 0;
|
||||
var playerCount = (Game_Config.Max && Game_Config.Max.PlayerCnt) || 4;
|
||||
var relPos = (targetSeat - selfSeat + playerCount) % playerCount;
|
||||
|
||||
// 显示槽 ind 与布局位 configIndex(2/3 人时两者不同)
|
||||
var slot = Game_Modify._resolveDisplaySlot(relPos, playerCount);
|
||||
if (!slot) return false;
|
||||
var ind = slot.ind, configIndex = slot.configIndex;
|
||||
|
||||
var player = Desk.PlayerList[targetSeat];
|
||||
// 空座位:隐藏该位玩家信息群组
|
||||
if (!player || !player.playerid || player.playerid === -1) {
|
||||
SpriteManager.hideGroup(43 + ind);
|
||||
return true;
|
||||
}
|
||||
|
||||
var posConfig = layout.POSITIONS[configIndex];
|
||||
if (!posConfig) return false;
|
||||
|
||||
// 底框(346+ind)
|
||||
if (posConfig.FRAME_X !== undefined) {
|
||||
SpriteManager.setPosition(346 + ind, posConfig.FRAME_X, posConfig.FRAME_Y);
|
||||
SpriteManager.setSize(346 + ind, posConfig.FRAME_WIDTH, posConfig.FRAME_HEIGHT);
|
||||
}
|
||||
|
||||
// 头像框(376+ind):基于底框 + 相对偏移
|
||||
var avatarX = posConfig.FRAME_X + posConfig.AVATAR.OFFSET_X;
|
||||
var avatarY = posConfig.FRAME_Y + posConfig.AVATAR.OFFSET_Y;
|
||||
var avatarWidth = posConfig.AVATAR.WIDTH;
|
||||
var avatarHeight = posConfig.AVATAR.HEIGHT;
|
||||
var nameOffsetX = posConfig.AVATAR.NAME_OFFSET_X || 0;
|
||||
var nameOffsetY = posConfig.AVATAR.NAME_OFFSET_Y || 0;
|
||||
var scoreOffsetX = posConfig.AVATAR.SCORE_OFFSET_X || 0;
|
||||
var scoreOffsetY = posConfig.AVATAR.SCORE_OFFSET_Y || 0;
|
||||
SpriteManager.setPosition(376 + ind, avatarX, avatarY);
|
||||
SpriteManager.setSize(376 + ind, avatarWidth, avatarHeight);
|
||||
|
||||
var textStyle = layout.TEXT_STYLE || {};
|
||||
var maxLen = textStyle.NAME_MAX_LENGTH || 8;
|
||||
var charWidth = textStyle.CHAR_WIDTH || 7;
|
||||
|
||||
// 昵称(406+ind)
|
||||
var nickname = Func.subString(player.nickname || '', maxLen, true);
|
||||
SpriteManager.setText(406 + ind, nickname);
|
||||
var nameX = avatarX + nameOffsetX;
|
||||
if (posConfig.NAME_CENTER_ALIGN) {
|
||||
var textWidth = (typeof nickname.gblen === 'function') ? nickname.gblen() * charWidth : nickname.length * charWidth;
|
||||
nameX = avatarX + avatarWidth / 2 - textWidth / 2;
|
||||
}
|
||||
SpriteManager.setPosition(406 + ind, nameX, avatarY + nameOffsetY);
|
||||
|
||||
// 分数(436+ind)
|
||||
var score = (typeof player.score === 'number') ? player.score : 0;
|
||||
SpriteManager.setText(436 + ind, score);
|
||||
var scoreX = avatarX + scoreOffsetX;
|
||||
if (posConfig.NAME_CENTER_ALIGN) {
|
||||
var scoreWidth = String(score).length * charWidth;
|
||||
scoreX = avatarX + avatarWidth / 2 - scoreWidth / 2;
|
||||
}
|
||||
SpriteManager.setPosition(436 + ind, scoreX, avatarY + scoreOffsetY);
|
||||
|
||||
// 头像图(116+ind):Func.up_imgurl 为平台头像加载接口(非引擎精灵原语)
|
||||
if (player.avatar && typeof Func !== 'undefined' && typeof Func.up_imgurl === 'function') {
|
||||
Func.up_imgurl(116 + ind, player.avatar);
|
||||
}
|
||||
|
||||
// 显示该座位玩家信息群组
|
||||
SpriteManager.showGroup(43 + ind);
|
||||
return true;
|
||||
};
|
||||
// 桌面文字聊天气泡:有 hook 委托子游戏;无 hook 时按【可变人数】默认渲染,使气泡贴合各玩家。
|
||||
// seat 为绝对座位;经 SpriteManager 操作精灵(背景552+ind/文字582+ind),位置取自 Game_Modify.BUBBLE_LAYOUT
|
||||
// 的物理位配置,尺寸(内边距/字宽/显示时长)复用 Game_Config.Chat/Max;不直接调引擎原语、不引用 codes。
|
||||
Game_Modify.ShowChat = function (seat, text) {
|
||||
if (window.SubGameHooks && SubGameHooks.ShowChat) return SubGameHooks.ShowChat(seat, text);
|
||||
GameUI.CloseChat();
|
||||
if (typeof Desk === 'undefined' || typeof C_Player === 'undefined' || typeof SpriteManager === 'undefined') return;
|
||||
var layout = Game_Modify.BUBBLE_LAYOUT;
|
||||
if (!layout || !layout.POSITIONS) return;
|
||||
var playerCount = (Game_Config.Max && Game_Config.Max.PlayerCnt) || 4;
|
||||
var relPos = (seat - C_Player.seat + playerCount) % playerCount;
|
||||
var slot = Game_Modify._resolveDisplaySlot(relPos, playerCount);
|
||||
if (!slot) return;
|
||||
var pos = layout.POSITIONS[slot.configIndex];
|
||||
if (!pos) return;
|
||||
var ind = slot.ind;
|
||||
|
||||
text = String(text);
|
||||
var chat = Game_Config.Chat || {};
|
||||
var dis_x = (chat.ChatDis && chat.ChatDis[0]) || 0;
|
||||
var dis_y = (chat.ChatDis && chat.ChatDis[1]) || 0;
|
||||
var text_w = chat.textwidth || 14;
|
||||
var text_len = (typeof text.gblen === 'function') ? text.gblen() : text.length;
|
||||
var bgW = text_len * text_w + dis_x * 2;
|
||||
|
||||
SpriteManager.setText(582 + ind, text);
|
||||
if (pos.IS_LEFT) {
|
||||
SpriteManager.setPosition(552 + ind, pos.X, pos.Y);
|
||||
SpriteManager.setPosition(582 + ind, pos.X + dis_x, pos.Y + dis_y);
|
||||
SpriteManager.setImage(552 + ind, layout.IMG_LEFT);
|
||||
} else {
|
||||
SpriteManager.setPosition(552 + ind, pos.X - bgW, pos.Y);
|
||||
SpriteManager.setPosition(582 + ind, pos.X - text_len * text_w - dis_x, pos.Y + dis_y);
|
||||
SpriteManager.setImage(552 + ind, layout.IMG_RIGHT);
|
||||
}
|
||||
SpriteManager.setWidth(552 + ind, bgW);
|
||||
SpriteManager.show(552 + ind);
|
||||
SpriteManager.show(582 + ind);
|
||||
|
||||
// 自动隐藏:复用平台配置的显示时长(观感与固定人数版一致),按槽位去重定时器
|
||||
var dur = (Game_Config.Max && Game_Config.Max.ShowChat) || 3000;
|
||||
Game_Modify._chatHideTimers = Game_Modify._chatHideTimers || {};
|
||||
if (Game_Modify._chatHideTimers[ind]) { clearTimeout(Game_Modify._chatHideTimers[ind]); }
|
||||
Game_Modify._chatHideTimers[ind] = setTimeout(function () {
|
||||
SpriteManager.hide(552 + ind);
|
||||
SpriteManager.hide(582 + ind);
|
||||
Game_Modify._chatHideTimers[ind] = null;
|
||||
}, dur);
|
||||
};
|
||||
|
||||
// 桌面语音气泡(播放):有 hook 委托子游戏;无 hook 时按【可变人数】默认渲染。
|
||||
// uiIndex 已是相对显示位序(relPos);经 SpriteManager 操作精灵(背景612+ind/内容642+ind),
|
||||
// 位置取自 Game_Modify.BUBBLE_LAYOUT,气泡宽度依据内容精灵当前宽度;尺寸复用 Game_Config.Voice。
|
||||
Game_Modify.gameui_play_voice = function (uiIndex) {
|
||||
if (window.SubGameHooks && SubGameHooks.gameui_play_voice) return SubGameHooks.gameui_play_voice(uiIndex);
|
||||
if (typeof SpriteManager === 'undefined') return;
|
||||
var layout = Game_Modify.BUBBLE_LAYOUT;
|
||||
if (!layout || !layout.POSITIONS) return;
|
||||
var playerCount = (Game_Config.Max && Game_Config.Max.PlayerCnt) || 4;
|
||||
var relPos = ((Number(uiIndex) % playerCount) + playerCount) % playerCount;
|
||||
var slot = Game_Modify._resolveDisplaySlot(relPos, playerCount);
|
||||
if (!slot) return;
|
||||
var pos = layout.POSITIONS[slot.configIndex];
|
||||
if (!pos) return;
|
||||
var ind = slot.ind;
|
||||
|
||||
var voice = Game_Config.Voice || {};
|
||||
var dis_x = (voice.VoiceDis && voice.VoiceDis[0]) || 0;
|
||||
var dis_y = (voice.VoiceDis && voice.VoiceDis[1]) || 0;
|
||||
var contentSize = SpriteManager.getSize(642 + ind);
|
||||
var text_len = (contentSize && typeof contentSize.width === 'number') ? contentSize.width : 0;
|
||||
var bgW = text_len + dis_x * 2;
|
||||
|
||||
if (pos.IS_LEFT) {
|
||||
SpriteManager.setPosition(612 + ind, pos.X, pos.Y);
|
||||
SpriteManager.setPosition(642 + ind, pos.X + dis_x, pos.Y + dis_y);
|
||||
SpriteManager.setImage(612 + ind, layout.IMG_LEFT);
|
||||
} else {
|
||||
SpriteManager.setPosition(612 + ind, pos.X - bgW, pos.Y);
|
||||
SpriteManager.setPosition(642 + ind, pos.X - text_len - dis_x, pos.Y + dis_y);
|
||||
SpriteManager.setImage(612 + ind, layout.IMG_RIGHT);
|
||||
}
|
||||
SpriteManager.setWidth(612 + ind, bgW);
|
||||
SpriteManager.show(612 + ind);
|
||||
SpriteManager.show(642 + ind);
|
||||
play_ani(1, 642 + ind, 43, 1, 3, 0, Game_Config.Voice.VoiceTime, 0, 0, 0, 0, 0, 0);
|
||||
};
|
||||
|
||||
// 桌面语音气泡(停止):有 hook 委托子游戏;无 hook 时隐藏对应槽位的语音气泡。
|
||||
Game_Modify.gameui_stop_voice = function (uiIndex) {
|
||||
if (window.SubGameHooks && SubGameHooks.gameui_stop_voice) return SubGameHooks.gameui_stop_voice(uiIndex);
|
||||
if (typeof SpriteManager === 'undefined') return;
|
||||
var playerCount = (Game_Config.Max && Game_Config.Max.PlayerCnt) || 4;
|
||||
var relPos = ((Number(uiIndex) % playerCount) + playerCount) % playerCount;
|
||||
var slot = Game_Modify._resolveDisplaySlot(relPos, playerCount);
|
||||
if (!slot) return;
|
||||
var ind = slot.ind;
|
||||
SpriteManager.hide(612 + ind);
|
||||
SpriteManager.hide(642 + ind);
|
||||
};
|
||||
@@ -1,36 +1,38 @@
|
||||
// ============================================================================
|
||||
// 00_SubGame_Config.template.js —— 平台配置项模板(结构由平台定义,子游戏填【值】)
|
||||
// 这是配置文件(C 类,非转发壳)。复制后按本游戏界面/玩法调整各项值。
|
||||
// 严格 ES5。
|
||||
// 游戏配置 (Game Configuration)
|
||||
// ============================================================================
|
||||
|
||||
var Game_Config = Game_Config || {};
|
||||
var Game_Config = Game_Config||{};//相关配置
|
||||
|
||||
|
||||
|
||||
Game_Config.Debugger={//调试配置
|
||||
Game_Config.Debugger={//调试配置
|
||||
isDebugger : true,// debugger模式下会将所有收发的包输出到控制台(正式发布改为false)
|
||||
AutoLogin : true,//debugger模式下是否需要记住登录状态自动登录(正式发布改为true)
|
||||
isSubmitError : false,//是否需要服务器收集错误信息调试时可根据需要(正式发布改为true)
|
||||
visitorLogin : true,//隐藏式游客登录
|
||||
isSubmitError : false,//是否需要服务器收集错误信息调试时可根据需要(正式发布改为true)
|
||||
visitorLogin : true,//隐藏式游客登录
|
||||
visiblePay:true,//审核通过后是否显示支付按钮
|
||||
serverType:1,//0->正式服务器 1->本地服务器 http://ylyxservice1.0791ts.cn/config/update_json.txt
|
||||
gameserver:""//子游戏填自己的更新地址
|
||||
};
|
||||
gameserver:"https://tsgames.daoqi88.cn/config_test/beta_update_jsonv2.txt"+"?"+ifast_random(100000)
|
||||
// gameserver:"https://tsgames.daoqi88.cn/config_test/test_update_jsonv2.txt"+"?"+ifast_random(100000)
|
||||
//gameserver:"https://gameotherwork.ld2sw.cn/update_json/update_json_haiwai.txt"+"?"+ifast_random(100000)
|
||||
// gameserver:"https://tsgames.daoqi88.cn/config/update_jsonv2.txt"+"?"+ifast_random(100000)
|
||||
|
||||
};
|
||||
|
||||
Game_Config.Max = {
|
||||
SumOfRoomtype:3,//创建时房间类型roomtype数组长度
|
||||
SumOfRoomtype:3,//创建时房间类型roomtype数组长度
|
||||
ShowChat:2000,//聊天停留时间
|
||||
PlayerCnt:4,//房间最大人数(按房间最大人数设置)
|
||||
PlayerCnt:4,//房间最大人数
|
||||
group:500,//游戏最大群组号
|
||||
showtime:10,//加载等待最少时间
|
||||
reconnecttime:30000,//唤醒游戏间隔(超过间隔断线重连)
|
||||
showtime:10,//加载等待最少时间
|
||||
reconnecttime:30000,//唤醒游戏间隔(超过间隔断线重连)
|
||||
Mainnickname:10,//主界面玩家昵称显示长度(字符长度)
|
||||
Infonickname:16//个人信息显示长度(字符长度)
|
||||
Infonickname:16//个人信息显示长度(字符长度)
|
||||
};
|
||||
Game_Config.Combat = {
|
||||
height:80,//战绩页单行高度高度
|
||||
up_y:190,//战绩页裁剪y坐标
|
||||
height:80,//战绩页单行高度高度
|
||||
up_y:190,//战绩页裁剪y坐标
|
||||
bannerheight:60,//战绩横幅高度
|
||||
bannery:80,//战绩横幅Y左边(相对48精灵)
|
||||
btnbg:50
|
||||
@@ -42,46 +44,46 @@ Game_Config.Info = {
|
||||
otherPositionDefault:true,//其他主界面玩家信息(昵称、积分)是否采用默认对齐方式对齐居中点为头像中点
|
||||
myPositionDefault:true,//其他主界面玩家信息(昵称、积分)是否采用默认对齐方式对齐居中点为头像中点
|
||||
myPosition:130,//自己信息对齐点(根据游戏界面自行修改)
|
||||
position:[],//其他主界面玩家信息(昵称、积分)居中对齐的x坐标 注意是其他玩家不包括自己从下家开始
|
||||
position:[],//其他主界面玩家信息(昵称、积分)居中对齐的x坐标 注意是其他玩家不包括自己从下家开始
|
||||
//TextContent:["1","2","3","4","5","6","7"],//常用语内容
|
||||
TextContent:["你好","谢谢","再来","快点","不要","加油",":)"],//常用语内容
|
||||
TextContentMp3:["","","","","","",""],//常用语对应音效
|
||||
TextContent:["你好","2","3","4","5","6","7"],//常用语内容
|
||||
TextContentMp3:["","","","","","",""],//常用语对应音效
|
||||
};
|
||||
Game_Config.Share={//分享参数
|
||||
appdownload:"",//下载链接(无需配置,从服务器获取)
|
||||
title:"游戏名",//(分享标题)
|
||||
description:"",//分享描述
|
||||
Game_Config.Share={//分享参数
|
||||
appdownload:"",//下载链接(无需配置,从服务器获取)
|
||||
title:"Test",//(分享标题)
|
||||
description:"hello world",//分享描述
|
||||
gameTitle:"",//游戏中的分享标题模板工程会自动将游戏名字分享出去、不必写在这个变量里
|
||||
gameDescription:""//游戏中分享描述
|
||||
gameDescription:""//游戏中分享描述
|
||||
};
|
||||
Game_Config.Chat={//游戏内聊天配置信息
|
||||
LimitLength:40,//聊天最大长度(字节长度)
|
||||
textwidth:12.5,//聊天显示文字的宽度(未改动聊天显示文字大小无需改动无需修改)
|
||||
ChatDis:[30,12],//聊天气泡与内容的间隔0位置左右间隔(最好不要低于30)1位置上下间隔
|
||||
isLeft:[1,0,0,1,1],//聊天气泡是否为以左边为基准线(坐标/基准按各游戏界面调整)
|
||||
ChatLoc:[[35,517],[1100,315],[1100,105],[175,105],[175,315]]//聊天气泡的基准点位置(注意是基准点位置!)(坐标/基准按各游戏界面调整)
|
||||
isLeft:[1,0,0,1,1],//聊天气泡是否为以左边为基准线
|
||||
ChatLoc:[[35,517],[1100,315],[1100,105],[175,105],[175,315]]//聊天气泡的基准点位置(注意是基准点位置!)
|
||||
|
||||
};
|
||||
Game_Config.Voice={//游戏内聊天配置信息
|
||||
VoiceTime:600,//播放语音动画的时间一般情况无需无需修改
|
||||
VoiceDis:[30,12],//语音气泡与内容的间隔0位置左右间隔(最好不要低于30)1位置上下间隔
|
||||
isLeft:[1,0,0,1,1],//气泡是否为以左边为基准线(坐标/基准按各游戏界面调整)
|
||||
VoiceLoc:[[35,517],[1100,315],[1100,105],[175,105],[175,315]]//气泡的基准点位置(注意是基准点位置!)(坐标/基准按各游戏界面调整)
|
||||
isLeft:[1,0,0,1,1],//气泡是否为以左边为基准线
|
||||
VoiceLoc:[[35,517],[1100,315],[1100,105],[175,105],[175,315]]//气泡的基准点位置(注意是基准点位置!)
|
||||
};
|
||||
Game_Config.Setting={
|
||||
Ads1:"本游戏仅供娱乐休闲使用,\n道具及虚拟货币不可兑换\n现金或实物,不代表任何\n真实财富价值。",
|
||||
//Ads2:"\n 或客服号:\n",
|
||||
board:"",//从后台获取设置无效
|
||||
Ads1:"本游戏仅为娱乐休\n闲使用,道具所有\n 游戏通用\n\n游戏问题请联系微\n 信公众号:\n",
|
||||
//Ads2:"\n 或客服号:\n",
|
||||
board:"",//从后台获取设置无效
|
||||
//info:[" 客服信息","QQ:","",""],//客服QQ提醒
|
||||
info:[" 客服信息","QQ:","手机:","微信:"],//客服QQ提醒
|
||||
board_blength:24,//通知页面一行最大字节数(无需设置)
|
||||
charge:"充值提示",//充值提示
|
||||
info:[" 客服信息","QQ:","手机:","微信:"],//客服QQ提醒
|
||||
board_blength:24,//通知页面一行最大字节数(无需设置)
|
||||
charge:"关注友乐微信公众号充值",//充值提示
|
||||
};
|
||||
Game_Config.Protocol={
|
||||
x:270,//协议图片初始x坐标
|
||||
x:270,//协议图片初始x坐标
|
||||
y:70,//协议图片初始y坐标
|
||||
h:560,//协议图片显示高度
|
||||
w:729//协议图片显示宽度
|
||||
h:560,//协议图片显示高度
|
||||
w:729//协议图片显示宽度
|
||||
};
|
||||
Game_Config.Help={//帮助
|
||||
x:300,//帮助图片初始x坐标
|
||||
@@ -89,27 +91,27 @@ Game_Config.Help={//帮助
|
||||
w:729,//帮助图片显示高度
|
||||
h:450//帮助图片显示宽度
|
||||
};
|
||||
Game_Config.Notice={//滚动公告
|
||||
x1:0,//无需设置
|
||||
x2:0,//无需设置
|
||||
y:0,//无需设置
|
||||
Game_Config.Notice={//滚动公告
|
||||
x1:0,//无需设置
|
||||
x2:0,//无需设置
|
||||
y:0,//无需设置
|
||||
h:0,//无需设置
|
||||
//以上参数用来截取滚动公告的显示,截取位置是与滚动公告底大小位置一致
|
||||
speed:0.1,//滚动公告的滚动速度
|
||||
width:15//滚动公告的内容字体的字节长度(汉字是两个字节)
|
||||
//以上参数用来截取滚动公告的显示,截取位置是与滚动公告底大小位置一致
|
||||
speed:0.1,//滚动公告的滚动速度
|
||||
width:15//滚动公告的内容字体的字节长度(汉字是两个字节)
|
||||
};
|
||||
Game_Config.Feedback = {//反馈配置
|
||||
maxLen:250 //反馈内容最大长度
|
||||
Game_Config.Feedback = {//反馈配置
|
||||
maxLen:250 //反馈内容最大长度
|
||||
};
|
||||
Game_Config.shakeList ={//摇一摇事件的回调ID、需要添加时在此处添加回调事件写在Utl_Input.js中的Utl.shakeEvent()中
|
||||
Game_Config.shakeList ={//摇一摇事件的回调ID、需要添加时在此处添加回调事件写在Utl_Input.js中的Utl.shakeEvent()中
|
||||
nil:0,
|
||||
startwar:1
|
||||
};
|
||||
Game_Config.soundList ={//声音资源名
|
||||
MenuSceneMusic:"",//大厅界面背景音
|
||||
MainSceneMusic:""//游戏主界面背景音
|
||||
Game_Config.soundList ={//声音资源名
|
||||
MenuSceneMusic:"",//大厅界面背景音
|
||||
MainSceneMusic:""//游戏主界面背景音
|
||||
};
|
||||
Game_Config.ClickButton = {//需要设置点击音效的按钮(只有有弹窗的按钮设置此音效有效、按钮已经设置好、子游戏不允许修改)
|
||||
Game_Config.ClickButton = {//需要设置点击音效的按钮(只有有弹窗的按钮设置此音效有效、按钮已经设置好、子游戏不允许修改)
|
||||
src_1:"",//点击时播放的声音资源文件( 不需要播放则不填,下同)
|
||||
src_2:""//弹窗时播放的音效
|
||||
}
|
||||
@@ -120,11 +122,28 @@ Game_Config.loginButton = {//登录按钮信息
|
||||
x3:488,//审核版本游客登录按钮x
|
||||
};
|
||||
Game_Config.sysConfig = {
|
||||
mainMenuButton:false,//是否进入主菜单界面隐藏四个按钮
|
||||
mainScenePlayerInfo:false,//是否隐藏主界面玩家信息
|
||||
mainSceneButton:false,//是否隐藏主界面按钮
|
||||
shareRoom:false,//接收到星星场是否屏蔽平台框架显示
|
||||
changeSeat:false,//是否屏蔽平台自动刷新换座后界面
|
||||
hideNotice:false,//隐藏公告栏
|
||||
vipInfinite:false,//是否为百人场
|
||||
mainMenuButton:false,//是否进入主菜单界面隐藏四个按钮
|
||||
mainScenePlayerInfo:false,//是否隐藏主界面玩家信息
|
||||
mainSceneButton:false,//是否隐藏主界面按钮
|
||||
shareRoom:false,//接收到星星场是否屏蔽平台框架显示
|
||||
changeSeat:false,//是否屏蔽平台自动刷新换座后界面
|
||||
hideNotice:false,//隐藏公告栏
|
||||
vipInfinite:false,//是否为百人场
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -46,6 +46,52 @@ Game_Modify.CreateRoomData = {
|
||||
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) {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// ============================================================================
|
||||
// 02_SubGame_Input.template.js —— 平台输入/回调接口「转发壳」模板(框架维护,子游戏不碰)
|
||||
// 02_SubGame_Input.js —— 平台输入/回调接口「转发壳」(框架维护,子游戏不碰)
|
||||
// 平台按全局名调用 gameHallImport.* / Game_Modify.*;本文件统一转发到 SubGameHooks 同名 hook。
|
||||
// 子游戏只需在 codes/ 的 SubGameHooks 里实现需要的接口(见 SubGameHooks.template.js)。
|
||||
// 子游戏只需在 codes/ 的 SubGameHooks 里实现需要的接口(见 codes/SubGameHooks.js)。
|
||||
// 严格 ES5。接口清单与默认值依据 spec §9。
|
||||
// ============================================================================
|
||||
|
||||
@@ -293,8 +293,210 @@ Game_Modify.getMaxPlayerCount = function (roomtype) {
|
||||
return (Game_Config.Max && Game_Config.Max.PlayerCnt) || 4;
|
||||
};
|
||||
|
||||
// B 类:更新玩家信息 UI,无 hook 返回 false(让平台默认处理)
|
||||
// 内部辅助(非平台接口):把相对显示位序 relPos 映射为 { ind:精灵槽, configIndex:物理布局位 }。
|
||||
// 2/3 人时 ind≠configIndex;无效返回 null。updatePlayerInfoUI 与桌面气泡默认实现共用此映射,
|
||||
// 保证头像面板与聊天/语音气泡落在同一玩家位。
|
||||
Game_Modify._resolveDisplaySlot = function (relPos, playerCount) {
|
||||
var ind = -1, configIndex = -1;
|
||||
if (playerCount === 2) {
|
||||
if (relPos === 0) { ind = 0; configIndex = 0; }
|
||||
else if (relPos === 1) { ind = 1; configIndex = 2; }
|
||||
} else if (playerCount === 3) {
|
||||
if (relPos === 0) { ind = 0; configIndex = 0; }
|
||||
else if (relPos === 1) { ind = 1; configIndex = 1; }
|
||||
else if (relPos === 2) { ind = 2; configIndex = 3; }
|
||||
} else {
|
||||
if (relPos === 0) { ind = 0; configIndex = 0; }
|
||||
else if (relPos === 1) { ind = 1; configIndex = 1; }
|
||||
else if (relPos === 2) { ind = 2; configIndex = 2; }
|
||||
else if (relPos === 3) { ind = 3; configIndex = 3; }
|
||||
}
|
||||
if (ind === -1) return null;
|
||||
return { ind: ind, configIndex: configIndex };
|
||||
};
|
||||
|
||||
// B 类:更新指定座位的玩家信息 UI(昵称/分数/头像)。
|
||||
// 有 hook 则委托子游戏;无 hook 时由本模板提供默认头像等 UI 的显示逻辑,其逻辑与子游戏
|
||||
// codes 内 GameView.updatePlayerInfoUI 保持一致,布局取自 Game_Modify.PLAYER_INFO_LAYOUT(见 01)。
|
||||
// 精灵操作一律经框架 SpriteManager(setPosition/setSize/setText/show|hideGroup),不直接调
|
||||
// set_self/set_group 等引擎原语;头像加载走平台 Func.up_imgurl(非精灵原语,SpriteManager 无对应能力)。
|
||||
// 不引用任何 codes 模块。平台 GameUI.updatePlayerInfoUI 会对每个座位逐一调用本接口,故按单座位渲染。
|
||||
Game_Modify.updatePlayerInfoUI = function (targetSeat) {
|
||||
if (window.SubGameHooks && SubGameHooks.updatePlayerInfoUI) return SubGameHooks.updatePlayerInfoUI(targetSeat);
|
||||
return false;
|
||||
|
||||
// ---- 模板默认:与 GameView.updatePlayerInfoUI 一致的单座位渲染 ----
|
||||
if (typeof Desk === 'undefined' || typeof C_Player === 'undefined' || typeof SpriteManager === 'undefined') return false;
|
||||
var layout = Game_Modify.PLAYER_INFO_LAYOUT;
|
||||
if (!layout || !layout.POSITIONS) return false;
|
||||
if (!Desk.PlayerList || targetSeat < 0 || targetSeat >= Desk.PlayerList.length) return false;
|
||||
|
||||
var selfSeat = (typeof C_Player.seat === 'number') ? C_Player.seat : 0;
|
||||
var playerCount = (Game_Config.Max && Game_Config.Max.PlayerCnt) || 4;
|
||||
var relPos = (targetSeat - selfSeat + playerCount) % playerCount;
|
||||
|
||||
// 显示槽 ind 与布局位 configIndex(2/3 人时两者不同)
|
||||
var slot = Game_Modify._resolveDisplaySlot(relPos, playerCount);
|
||||
if (!slot) return false;
|
||||
var ind = slot.ind, configIndex = slot.configIndex;
|
||||
|
||||
var player = Desk.PlayerList[targetSeat];
|
||||
// 空座位:隐藏该位玩家信息群组
|
||||
if (!player || !player.playerid || player.playerid === -1) {
|
||||
SpriteManager.hideGroup(43 + ind);
|
||||
return true;
|
||||
}
|
||||
|
||||
var posConfig = layout.POSITIONS[configIndex];
|
||||
if (!posConfig) return false;
|
||||
|
||||
// 底框(346+ind)
|
||||
if (posConfig.FRAME_X !== undefined) {
|
||||
SpriteManager.setPosition(346 + ind, posConfig.FRAME_X, posConfig.FRAME_Y);
|
||||
SpriteManager.setSize(346 + ind, posConfig.FRAME_WIDTH, posConfig.FRAME_HEIGHT);
|
||||
}
|
||||
|
||||
// 头像框(376+ind):基于底框 + 相对偏移
|
||||
var avatarX = posConfig.FRAME_X + posConfig.AVATAR.OFFSET_X;
|
||||
var avatarY = posConfig.FRAME_Y + posConfig.AVATAR.OFFSET_Y;
|
||||
var avatarWidth = posConfig.AVATAR.WIDTH;
|
||||
var avatarHeight = posConfig.AVATAR.HEIGHT;
|
||||
var nameOffsetX = posConfig.AVATAR.NAME_OFFSET_X || 0;
|
||||
var nameOffsetY = posConfig.AVATAR.NAME_OFFSET_Y || 0;
|
||||
var scoreOffsetX = posConfig.AVATAR.SCORE_OFFSET_X || 0;
|
||||
var scoreOffsetY = posConfig.AVATAR.SCORE_OFFSET_Y || 0;
|
||||
SpriteManager.setPosition(376 + ind, avatarX, avatarY);
|
||||
SpriteManager.setSize(376 + ind, avatarWidth, avatarHeight);
|
||||
|
||||
var textStyle = layout.TEXT_STYLE || {};
|
||||
var maxLen = textStyle.NAME_MAX_LENGTH || 8;
|
||||
var charWidth = textStyle.CHAR_WIDTH || 7;
|
||||
|
||||
// 昵称(406+ind)
|
||||
var nickname = Func.subString(player.nickname || '', maxLen, true);
|
||||
SpriteManager.setText(406 + ind, nickname);
|
||||
var nameX = avatarX + nameOffsetX;
|
||||
if (posConfig.NAME_CENTER_ALIGN) {
|
||||
var textWidth = (typeof nickname.gblen === 'function') ? nickname.gblen() * charWidth : nickname.length * charWidth;
|
||||
nameX = avatarX + avatarWidth / 2 - textWidth / 2;
|
||||
}
|
||||
SpriteManager.setPosition(406 + ind, nameX, avatarY + nameOffsetY);
|
||||
|
||||
// 分数(436+ind)
|
||||
var score = (typeof player.score === 'number') ? player.score : 0;
|
||||
SpriteManager.setText(436 + ind, score);
|
||||
var scoreX = avatarX + scoreOffsetX;
|
||||
if (posConfig.NAME_CENTER_ALIGN) {
|
||||
var scoreWidth = String(score).length * charWidth;
|
||||
scoreX = avatarX + avatarWidth / 2 - scoreWidth / 2;
|
||||
}
|
||||
SpriteManager.setPosition(436 + ind, scoreX, avatarY + scoreOffsetY);
|
||||
|
||||
// 头像图(116+ind):Func.up_imgurl 为平台头像加载接口(非引擎精灵原语)
|
||||
if (player.avatar && typeof Func !== 'undefined' && typeof Func.up_imgurl === 'function') {
|
||||
Func.up_imgurl(116 + ind, player.avatar);
|
||||
}
|
||||
|
||||
// 显示该座位玩家信息群组
|
||||
SpriteManager.showGroup(43 + ind);
|
||||
return true;
|
||||
};
|
||||
// 桌面文字聊天气泡:有 hook 委托子游戏;无 hook 时按【可变人数】默认渲染,使气泡贴合各玩家。
|
||||
// seat 为绝对座位;经 SpriteManager 操作精灵(背景552+ind/文字582+ind),位置取自 Game_Modify.BUBBLE_LAYOUT
|
||||
// 的物理位配置,尺寸(内边距/字宽/显示时长)复用 Game_Config.Chat/Max;不直接调引擎原语、不引用 codes。
|
||||
Game_Modify.ShowChat = function (seat, text) {
|
||||
if (window.SubGameHooks && SubGameHooks.ShowChat) return SubGameHooks.ShowChat(seat, text);
|
||||
GameUI.CloseChat();
|
||||
if (typeof Desk === 'undefined' || typeof C_Player === 'undefined' || typeof SpriteManager === 'undefined') return;
|
||||
var layout = Game_Modify.BUBBLE_LAYOUT;
|
||||
if (!layout || !layout.POSITIONS) return;
|
||||
var playerCount = (Game_Config.Max && Game_Config.Max.PlayerCnt) || 4;
|
||||
var relPos = (seat - C_Player.seat + playerCount) % playerCount;
|
||||
var slot = Game_Modify._resolveDisplaySlot(relPos, playerCount);
|
||||
if (!slot) return;
|
||||
var pos = layout.POSITIONS[slot.configIndex];
|
||||
if (!pos) return;
|
||||
var ind = slot.ind;
|
||||
|
||||
text = String(text);
|
||||
var chat = Game_Config.Chat || {};
|
||||
var dis_x = (chat.ChatDis && chat.ChatDis[0]) || 0;
|
||||
var dis_y = (chat.ChatDis && chat.ChatDis[1]) || 0;
|
||||
var text_w = chat.textwidth || 14;
|
||||
var text_len = (typeof text.gblen === 'function') ? text.gblen() : text.length;
|
||||
var bgW = text_len * text_w + dis_x * 2;
|
||||
|
||||
SpriteManager.setText(582 + ind, text);
|
||||
if (pos.IS_LEFT) {
|
||||
SpriteManager.setPosition(552 + ind, pos.X, pos.Y);
|
||||
SpriteManager.setPosition(582 + ind, pos.X + dis_x, pos.Y + dis_y);
|
||||
SpriteManager.setImage(552 + ind, layout.IMG_LEFT);
|
||||
} else {
|
||||
SpriteManager.setPosition(552 + ind, pos.X - bgW, pos.Y);
|
||||
SpriteManager.setPosition(582 + ind, pos.X - text_len * text_w - dis_x, pos.Y + dis_y);
|
||||
SpriteManager.setImage(552 + ind, layout.IMG_RIGHT);
|
||||
}
|
||||
SpriteManager.setWidth(552 + ind, bgW);
|
||||
SpriteManager.show(552 + ind);
|
||||
SpriteManager.show(582 + ind);
|
||||
|
||||
// 自动隐藏:复用平台配置的显示时长(观感与固定人数版一致),按槽位去重定时器
|
||||
var dur = (Game_Config.Max && Game_Config.Max.ShowChat) || 3000;
|
||||
Game_Modify._chatHideTimers = Game_Modify._chatHideTimers || {};
|
||||
if (Game_Modify._chatHideTimers[ind]) { clearTimeout(Game_Modify._chatHideTimers[ind]); }
|
||||
Game_Modify._chatHideTimers[ind] = setTimeout(function () {
|
||||
SpriteManager.hide(552 + ind);
|
||||
SpriteManager.hide(582 + ind);
|
||||
Game_Modify._chatHideTimers[ind] = null;
|
||||
}, dur);
|
||||
};
|
||||
|
||||
// 桌面语音气泡(播放):有 hook 委托子游戏;无 hook 时按【可变人数】默认渲染。
|
||||
// uiIndex 已是相对显示位序(relPos);经 SpriteManager 操作精灵(背景612+ind/内容642+ind),
|
||||
// 位置取自 Game_Modify.BUBBLE_LAYOUT,气泡宽度依据内容精灵当前宽度;尺寸复用 Game_Config.Voice。
|
||||
Game_Modify.gameui_play_voice = function (uiIndex) {
|
||||
if (window.SubGameHooks && SubGameHooks.gameui_play_voice) return SubGameHooks.gameui_play_voice(uiIndex);
|
||||
if (typeof SpriteManager === 'undefined') return;
|
||||
var layout = Game_Modify.BUBBLE_LAYOUT;
|
||||
if (!layout || !layout.POSITIONS) return;
|
||||
var playerCount = (Game_Config.Max && Game_Config.Max.PlayerCnt) || 4;
|
||||
var relPos = ((Number(uiIndex) % playerCount) + playerCount) % playerCount;
|
||||
var slot = Game_Modify._resolveDisplaySlot(relPos, playerCount);
|
||||
if (!slot) return;
|
||||
var pos = layout.POSITIONS[slot.configIndex];
|
||||
if (!pos) return;
|
||||
var ind = slot.ind;
|
||||
|
||||
var voice = Game_Config.Voice || {};
|
||||
var dis_x = (voice.VoiceDis && voice.VoiceDis[0]) || 0;
|
||||
var dis_y = (voice.VoiceDis && voice.VoiceDis[1]) || 0;
|
||||
var contentSize = SpriteManager.getSize(642 + ind);
|
||||
var text_len = (contentSize && typeof contentSize.width === 'number') ? contentSize.width : 0;
|
||||
var bgW = text_len + dis_x * 2;
|
||||
|
||||
if (pos.IS_LEFT) {
|
||||
SpriteManager.setPosition(612 + ind, pos.X, pos.Y);
|
||||
SpriteManager.setPosition(642 + ind, pos.X + dis_x, pos.Y + dis_y);
|
||||
SpriteManager.setImage(612 + ind, layout.IMG_LEFT);
|
||||
} else {
|
||||
SpriteManager.setPosition(612 + ind, pos.X - bgW, pos.Y);
|
||||
SpriteManager.setPosition(642 + ind, pos.X - text_len - dis_x, pos.Y + dis_y);
|
||||
SpriteManager.setImage(612 + ind, layout.IMG_RIGHT);
|
||||
}
|
||||
SpriteManager.setWidth(612 + ind, bgW);
|
||||
SpriteManager.show(612 + ind);
|
||||
SpriteManager.show(642 + ind);
|
||||
play_ani(1, 642 + ind, 43, 1, 3, 0, Game_Config.Voice.VoiceTime, 0, 0, 0, 0, 0, 0);
|
||||
};
|
||||
|
||||
// 桌面语音气泡(停止):有 hook 委托子游戏;无 hook 时隐藏对应槽位的语音气泡。
|
||||
Game_Modify.gameui_stop_voice = function (uiIndex) {
|
||||
if (window.SubGameHooks && SubGameHooks.gameui_stop_voice) return SubGameHooks.gameui_stop_voice(uiIndex);
|
||||
if (typeof SpriteManager === 'undefined') return;
|
||||
var playerCount = (Game_Config.Max && Game_Config.Max.PlayerCnt) || 4;
|
||||
var relPos = ((Number(uiIndex) % playerCount) + playerCount) % playerCount;
|
||||
var slot = Game_Modify._resolveDisplaySlot(relPos, playerCount);
|
||||
if (!slot) return;
|
||||
var ind = slot.ind;
|
||||
SpriteManager.hide(612 + ind);
|
||||
SpriteManager.hide(642 + ind);
|
||||
};
|
||||
Reference in New Issue
Block a user