//导入用户信息类 cc.Class({ extends: cc.BaseClass, properties: { //左侧标签按钮 // hallTab: { // default: null, // type: cc.Button, // displayName: '大厅聊天标签' // }, // privateChatTab: { // default: null, // type: cc.Button, // displayName: '私聊聊天标签' // }, //聊天滚动区 ScrollView: { default: null, type: cc.ScrollView, displayName: '消息滚动视图' }, content: { default: null, type: cc.Node, displayName: '消息内容容器' }, // 消息项预制体 itemOtherPrefab: { default: null, type: cc.Prefab, displayName: '消息项' }, // 输入区 inputBox: { default: null, type: cc.EditBox, displayName: '输入框' }, sendBtn: { default: null, type: cc.Button, displayName: '发送按钮' }, //添加快捷聊天按钮 quickChatBtn: { default: null, type: cc.Button, displayName: '快捷聊天按钮' }, //快捷聊天消息面板 quickChatPanel: { default: null, type: cc.Node, displayName: '快捷聊天面板' }, //快捷聊天消息列表 quickChatList: { default: null, type: cc.Node, displayName: '快捷聊天列表' }, // quickChatMessages: [ // '大家好!', // '玩得开心!', // '这把牌不错!', // '加油!', // '谢谢!', // '不好意思,有点事', // '稍等一下', // '继续继续', // '这把运气不错', // '下次再玩' // ], }, SetHook: function (Hook) { this.m_Hook = Hook; }, start() { // 注册聊天消息接收回调 this.registerChatCallback(); }, onLoad() { }, bindEvents() { // 绑定发送按钮 if (this.sendBtn) { this.sendBtn.node.on('click', this.onClickSendMessage, this); } // 绑定输入框回车事件 if (this.inputBox) { this.inputBox.node.on('editing-return', this.onClickSendMessage, this); } // 绑定快捷聊天按钮 if (this.quickChatBtn) { this.quickChatBtn.node.on('click', this.onClickQuickChat, this); } // 绑定快捷聊天列表项点击事件 if (this.quickChatList) { for (let i = 0; i < this.quickChatList.childrenCount; i++) { this.quickChatList.children[i].on('click', this.onClickQuickChatItem, this); } } }, // 注册聊天消息接收回调 registerChatCallback: function () { // 保存原始回调函数 var originalChatCallback = window.gClubClientKernel.onSocketChat; // 重写聊天消息接收回调 window.gClubClientKernel.onSocketChat = function (data, size) { // 先调用原始回调 var result = originalChatCallback.call(this, data, size); // 处理聊天消息显示 var chatObj = new CMD_S_UserChat(); gCByte.Bytes2Str(chatObj, data); // 显示聊天消息 this.onReceiveChatMessage(chatObj.dwSendUserID, chatObj.szChatString); return result; }.bind(this); }, // 接收聊天消息并显示 onReceiveChatMessage: async function (sendUserID, message) { // 获取发送者信息 let webUrl = window.PHP_HOME + '/UserFunc.php?GetMark=12&dwUserID=' + sendUserID; WebCenter.GetData(webUrl, null, function (data) { var senderInfo = JSON.parse(data); // 获取发送者昵称 var senderName = senderInfo.NickName; //获取发送者头像URL var senderHeadUrl = senderInfo.HeadUrl; // 创建消息项并显示 this.createChatItem(senderName, message, sendUserID, senderHeadUrl); // var senderInfo = await this.getUserInfo(sendUserID); }.bind(this)); }, // 创建聊天消息项 createChatItem: function (senderName, message, userID, senderHeadUrl) { // 克隆消息项模板 var chatItem = cc.instantiate(this.itemOtherPrefab); // 添加到内容容器 this.content.addChild(chatItem); //设置消息项的的整体位置 this.updateChatItem(chatItem); // 设置发送时间 var labelTime = chatItem.getChildByName('LabelTime'); if (labelTime) { var now = new Date(); var timeString = now.getHours().toString().padStart(2, '0') + ':' + now.getMinutes().toString().padStart(2, '0'); labelTime.getComponent(cc.Label).string = timeString; } // 设置发送者昵称 var Labelname = chatItem.getChildByName('LabelName'); if (Labelname) { Labelname.getComponent(cc.Label).string = senderName; } // 设置发送者头像 var spriteAvater = chatItem.getChildByName('LabelName').getChildByName('SpriteAvater'); // 设置消息内容 var spriteChat = chatItem.getChildByName('SpriteChat'); if (spriteChat) { // 设置消息内容文本 var chatLabel = spriteChat.getChildByName('LabelChat') var chatLabelStr = chatLabel.getComponent(cc.Label); if (chatLabelStr) { // 设置Label文本内容 chatLabelStr.string = message; //设置气泡框跟随文字大小变化 this.setChatBubbleSize(chatLabelStr, spriteChat); } } // 更新滚动视图位置,滚动到底部 this.autoScrollToBottom(); }, //更新消息项的子节点的大小和位置(也可以修改样式之类的属性) updateChatItem(chatItem) { //获取消息项下的所有子节点 var children = chatItem.children; //时间文本 //昵称文本 设置文字大小 children[2].getComponent(cc.Label).fontSize = 20; //气泡文本 //设置文字大小 children[3].getChildByName('LabelChat').getComponent(cc.Label).fontSize = 40; }, //设置气泡框跟随文字大小变化 setChatBubbleSize(chatLabelStr, spriteChat) { //等待一帧让Label渲染完成,然后调整气泡框大小 this.scheduleOnce(() => { // 使用Canvas API精确测量文本尺寸 var textWidth = 0; var textHeight = 0; //文本框的最大宽度 var maxWidth = 724; // 获取Label的字体设置 var fontSize = chatLabelStr.fontSize; var fontFamily = 'Arial'; // 默认字体 // 创建临时canvas来测量文本 var canvas = document.createElement('canvas'); var ctx = canvas.getContext('2d'); // 设置字体样式 ctx.font = fontSize + 'px ' + fontFamily; // 分割文本为多行 var lines = chatLabelStr.string.split('\n'); var maxLineWidth = 0; // 测量每行文本的宽度 for (var i = 0; i < lines.length; i++) { var metrics = ctx.measureText(lines[i]); if (metrics.width > maxLineWidth) { maxLineWidth = metrics.width; } } textWidth = maxLineWidth; textHeight = lines.length * fontSize + (lines.length - 1) * 10; // 行间距为5px //获取文本框的大小 var textsize = chatLabelStr.node.getContentSize(); //获取气泡框的大小 var bubbleSize = spriteChat.getContentSize(); //设置气泡框的新大小 和文本框的新大小 if (textWidth > 724) { //设置气泡框的新大小 spriteChat.setContentSize(maxWidth + 20, textsize.height); //设置文本框的新大小 chatLabelStr.node.setContentSize(maxWidth, textsize.height + 20); } else { //设置气泡框的新大小 spriteChat.setContentSize(textWidth + 20, textHeight + 20); //设置文本框的新大小 chatLabelStr.node.setContentSize(textWidth, textHeight); } // console.log('======================', this.content); //获取换行之后的行数 var lineCount = this.getLineCount(chatLabelStr.string, maxWidth); // if (lineCount >= 3) { // //增加下个消息项之间的上下间距 // var layout = this.content.getComponent(cc.Layout); // layout.paddingBottom = 20; // } }, 0.1); // 延迟0.1秒执行,确保文字渲染完成 }, //计算获取换行之后文本的行数 getLineCount(text, maxWidth) { var text = text; var fontSize = 40; // 创建Canvas进行测量 var canvas = document.createElement('canvas'); var ctx = canvas.getContext('2d'); ctx.font = fontSize + 'px Arial'; var words = text.split(''); var currentLine = ''; var lines = []; for (var i = 0; i < words.length; i++) { var testLine = currentLine + words[i]; var metrics = ctx.measureText(testLine); // 如果超过最大宽度,换行 if (metrics.width > maxWidth && currentLine !== '') { lines.push(currentLine); currentLine = words[i]; } else { currentLine = testLine; } } // 添加最后一行 if (currentLine !== '') { lines.push(currentLine); } return lines.length; }, // 自动滚动到底部 autoScrollToBottom() { this.scheduleOnce(() => { // 设置ScrollView的垂直滚动位置为0(底部) // Cocos2.4中,ScrollView的verticalScrollOffset:0=底部,最大值=顶部 this.ScrollView.verticalScrollOffset = 0; // 强制刷新ScrollView this.ScrollView.scrollToBottom(0.1); // 0.1秒平滑滚动,传0则瞬间到位 }, 0); // 延迟0帧,等待UI布局更新完成 }, // 点击发送聊天消息 onClickSendMessage() { // console.log('=====发送按钮点击'); const message = this.inputBox ? this.inputBox.string.trim() : ''; if (!message) { return; } //获取用户ID - 从全局用户信息中获取当前登录用户的真实ID const userID = g_GlobalUserInfo ? g_GlobalUserInfo.GetGlobalUserData().dwUserID : 0; if (!userID) { console.error('无法获取当前用户ID,用户可能未登录'); return; } // 这里调用发送消息的方法 window.gClubClientKernel.onSendChat(userID, message); //点击发送按钮时,调用发送消息方法,会将输入框的信息清空 this.clearInput(); }, //点击快捷聊天按钮, onClickQuickChat(event, customEventData) { // console.log('=====快捷聊天按钮点击'); // console.log('快捷聊天按钮点击===>', this.quickChatList.childrenCount); //显示快捷聊天面板 if (this.quickChatPanel) { this.quickChatPanel.active = true; } }, //快速选择聊天文本项点击事件 onClickQuickChatItem(event) { // console.log('=====快捷聊天文本项点击'); //获取孩子节点 var labelnode = event.target.children[0].children[0]; //获取对应的聊天消息 var message = labelnode.getComponent(cc.Label).string; if (message) { //将消息设置到输入框 this.inputBox.string = message; } //隐藏快捷聊天面板 if (this.quickChatPanel) { this.quickChatPanel.active = false; } }, clearInput() { if (this.inputBox) { this.inputBox.string = ''; } }, });