local ChatDefine = require("luaScript.GameChatDefine") local ChatView = class("ChatView", cc.UIView) MESSAGE_RECT = { [300] = cc.rect(60,57,5,0), [301] = cc.rect(60,50,0,0), [302] = cc.rect(70,57,5,0), [303] = cc.rect(70,55,0,0), [304] = cc.rect(55,55,0,0), [305] = cc.rect(60,50,0,0), } --[[ -- 使用方法 function XXRoomView:initChatView() ... local messageList = {} local headInfos = {} self.chatView = import("luaScript.Views.Room.ChatView"):new(messageList, headInfos, showBtn) self:addChild(self.chatView) end -- messageList = { chatList = { [1] = {oggStandard = "", oggLocal = "", txt = "各位前辈,我要开车了!"}, [2] = {oggStandard = "", oggLocal = "", txt = "今天牌真是太好了!"}, [3] = {oggStandard = "", oggLocal = "", txt = "快点啦!准备开局!"}, [4] = {oggStandard = "", oggLocal = "", txt = "你们打的好,但是我要自摸了"}, [5] = {oggStandard = "", oggLocal = "", txt = "牌神来了,让座让座!"}, [6] = {oggStandard = "", oggLocal = "", txt = "稍等一下,我拉个朋友"}, [7] = {oggStandard = "", oggLocal = "", txt = "时间很宝贵的,快点出牌吧"}, [8] = {oggStandard = "", oggLocal = "", txt = "辛苦十几年,一把回到解放前!!"}, [9] = {oggStandard = "", oggLocal = "", txt = "等下再来一把!"}, }, --采用plist faceList = { [1] = {oggStandard = "", oggLocal = "", btnPng = "face_j_1001.png", aniFile = "res/ui/zy_tongyong/zy_face/face1_anims_i6p.plist", aniString = "face1_%d.png", frameNum = 10}, [2] = {oggStandard = "", oggLocal = "", btnPng = "face_j_1002.png", aniFile = "res/ui/zy_tongyong/zy_face/face2_anims_i6p.plist", aniString = "face2_%d.png", frameNum = 10}, [3] = {oggStandard = "", oggLocal = "", btnPng = "face_j_1003.png", aniFile = "res/ui/zy_tongyong/zy_face/face3_anims_i6p.plist", aniString = "face3_%d.png", frameNum = 10}, [4] = {oggStandard = "", oggLocal = "", btnPng = "face_j_1004.png", aniFile = "res/ui/zy_tongyong/zy_face/face4_anims_i6p.plist", aniString = "face4_%d.png", frameNum = 10}, [5] = {oggStandard = "", oggLocal = "", btnPng = "face_j_1005.png", aniFile = "res/ui/zy_tongyong/zy_face/face5_anims_i6p.plist", aniString = "face5_%d.png", frameNum = 10}, }, } -- 玩家头像所在的节点 voiceDir不定义将会根据屏幕的中心判断是左边还是右边 headInfos = { [1] = {headPos = cc.p(0,0), voiceDir = 1}, [2] = {headPos = cc.p(0,0), voiceDir = 1}, [3] = {headPos = cc.p(0,0), voiceDir = 1}, [4] = {headPos = cc.p(0,0), voiceDir = 1}, [5] = {headPos = cc.p(0,0), voiceDir = 1}, [6] = {headPos = cc.p(0,0), voiceDir = 1}, [7] = {headPos = cc.p(0,0), voiceDir = 1}, [8] = {headPos = cc.p(0,0), voiceDir = 1}, } -- 是否直接显示表情和语音按钮 showBtn : true or false --]] function ChatView:ctor(messageList, headInfos, showBtn) ChatView.super.ctor(self); self.messageList = {}; self.headInfos = headInfos; self.showBtn = showBtn; self.messageList.chatList = messageList.chatList or messageList --兼容老的数据格式 self.messageList.faceList = messageList.faceList or ChatDefine.FaceConfigs local ui = loadUI("res/ui/ui_fangjian/ui_fangjian_chat.ui"); self.ui = ui; self:addChild(ui); self.uiHeads = {} -- 是否说普通话 self.isStandardLanguage = true self.recording = false; -- 是否正在录音 --是否关闭点击信息 self.m_isClose = true --系统的音效状态 self.soundState = app.systemSetting.info.sound -- 记录每个玩家的最后一条语音 self.playerVoice = {} --[[ self.playerVoice = { [1] = {url = url, filePath = filePath, recordTime = recordTime}, [2] = {url = url, filePath = filePath, recordTime = recordTime}, [3] = {url = url, filePath = filePath, recordTime = recordTime}, [4] = {url = url, filePath = filePath, recordTime = recordTime}, [5] = {url = url, filePath = filePath, recordTime = recordTime}, } --]] -- 最后一条音效 self.lastSound = nil -- 正在说话的椅子号(同一时刻只允许一个玩家说话) self.lastSpeakingSeatId = false -- 我的视图椅子号 self.myViewId = 1; -- 道具播放器 self.propAniPlayer = import("luaScript.Tools.PropAniPlayer"):new() -- 房间内存在的玩家ID self.uids = {} --是否显示道具动画 self.isPropEnabled = true --是否播放语音 self.isVoiceEnabled = true self.recordingTime = os.time() --ID 默认显示,金币场隐藏(不能暴露机器人ID) self.IDbVisible = true self.voicepropid = 0 self.messagepropid = 0 if app.php.mypropdata then for k,v in pairs(app.php.mypropdata) do if v.prop_id and v.prop_id >= 400 and v.prop_id < 500 then self.voicepropid = v.prop_id end if v.prop_id and v.prop_id >= 300 and v.prop_id < 400 then self.messagepropid = v.prop_id end end end end -- 设置是否说普通话 function ChatView:setLanguage(isStandard) self.isStandardLanguage = isStandard end -- 显示表情和语音按钮 -- 个别游戏在刚进入房间还没坐下时是不允许显示这两个按钮的 function ChatView:showBtns() self.ui.Items.Button_Face:setVisible(true) self.ui.Items.Button_Voice:setVisible(true) end function ChatView:hideBtns() self.ui.Items.Button_Face:setVisible(false) self.ui.Items.Button_Voice:setVisible(false) end function ChatView:hideFace() self.ui.Items.Button_Face:setVisible(false) end function ChatView:hideVoice() self.ui.Items.Button_Voice:setVisible(false) end -- 添加一个玩家 function ChatView:addPlayer(uid) self.uids[uid] = true end -- 删除一个玩家 function ChatView:delPlayer(uid) self.uids[uid] = nil end function ChatView:setPlayerUids(uids) --self.uids = {} self.uids = uids if not self.myViewId then self.myViewId = app.room:getViewIdByUserId(app.user.loginInfo.uid) end end function ChatView:setBtnFace(pos,img) if pos then if pos.x < 1 and pos.y < 1 then self.ui.Items.Button_Face:setPositionPercent(pos) else self.ui.Items.Button_Face:setPosition(pos) end end if img then self.ui.Items.Button_Face:loadTextureNormal(img, cc.TextureResType.plistType) self.ui.Items.Button_Face:loadTexturePressed(img, cc.TextureResType.plistType) self.ui.Items.Button_Face:loadTextureDisabled(img, cc.TextureResType.plistType) end end function ChatView:setBtnVoice(pos,img) if pos then if pos.x < 1 and pos.y < 1 then self.ui.Items.Button_Voice:setPositionPercent(pos) else self.ui.Items.Button_Voice:setPosition(pos) end end if img then self.ui.Items.Button_Voice:loadTextureNormal(img, cc.TextureResType.plistType) self.ui.Items.Button_Voice:loadTexturePressed(img, cc.TextureResType.plistType) self.ui.Items.Button_Voice:loadTextureDisabled(img, cc.TextureResType.plistType) end end function ChatView:setPropEnabled(enable) self.isPropEnabled = enable end function ChatView:setVoiceEnabled(enable) self.isVoiceEnabled = enable end -- 重新播放某个玩家说过的话 function ChatView:replayRecord(uid) local nSeatShowId = app.room:getViewIdByUserId(uid) if nSeatShowId then self:_replayRecord(nSeatShowId); end end function ChatView:onEnter() ChatView.super.onEnter(self) local nMyUserId = app.user.loginInfo.uid self.myViewId = app.room:getViewIdByUserId(nMyUserId) -- 初期只加载按钮会用得到的纹理 -- loadSpriteFrameFile(ChatDefine.FaceBtnFile) -- 点击表情按钮打开表情界面 self.ui.Items.Button_Face:registerClick(handler(self , self.onClickOpenFace)) -- 点击空白区域会关闭表情界面 self.ui.Items.Layout_FaceMenu:registerClick(handler(self , self.onClickCloseFace)) -- 监听服务器下发的聊天事件 self.ui:bindEvent(app.user, "onChatMessageResponse", handler(self, self.onChatMessageResponse)) --绑定change音效 self:bindEvent(app , "onChangeYinXiao" , handler(self , self.onChangeYinXiao)); -- 语音按钮 -- self:initVoiceTouchEvent() -- self.ui.Items.Button_Voice:registerClick(handler(self , self.stopRecord), handler(self , self.beginRecord), handler(self , self.stopRecord)); self.ui.Items.Button_Voice:registerClick(handler(self , self.stopGRecord), handler(self , self.beginGRecord), handler(self , self.stopGRecord)); -- 发送按钮 self.ui.Items.Button_Send:registerClick(handler(self , self.onClickSend)); -- self.ui.Items.Button_Voice:addTouchEventListener(handler(self, self.onTouchEvent)) -- 录音成功的回调 -- app:dispatchEvent({name = "recordCallback", filePath = info.filePath, recordUrl = info.recordUrl, recordTime = info.recordTime }); self:bindEvent(app , "recordCallback" , handler(self , self.recordCallback)); -- 录制完成回调,Gvoice self:bindEvent(app , "recordGCallback" , handler(self , self.recordGCallback)) --登录成功后获取到个人的道具id self:bindEvent(app,"PHP_LGIN_SUCCESSED",handler(self , self.onLoadMyProp)) -- 头像上的语音节点 self.templateHead = self.ui.Items.Layout_Head self.templateHead:setVisible(false) -- 快捷语 self.templateMessage = self.ui.Items.Layout_Message; self.templateMessage:setVisible(false) -- 表情 self.templateFace = self.ui.Items.Layout_Face; self.templateFace:setVisible(false) --聊天 self.templateChatOther = self.ui.Items.Layout_Chat_Other; self.templateChatOther:setVisible(false) self.templateChatMy = self.ui.Items.Layout_Chat_My; self.templateChatMy:setVisible(false) -- self.ImageView_Line_Face:setVisible(false) -- 创建每个椅子对应的语音头像节点 local uiLayoutHeads = self.ui.Items.Layout_Heads for idx, headInfo in ipairs(self.headInfos) do local uiHead = self:createHeadItem(headInfo.voiceDir, headInfo.headPos) uiHead:setAnchorPoint(cc.p(0.5, 0.5)) uiHead:setPosition(headInfo.headPos or cc.p(50*idx, 50*idx)) uiLayoutHeads:addChild(uiHead) local szHead = uiHead:getContentSize() uiHead:registerClick(function() self:onClickPlayerHead(idx, szHead) end) self.uiHeads[idx] = uiHead end -- 初始化快捷语 local uiScrollMessage = self.ui.Items.ScrollView_Message uiScrollMessage:removeAllChildren() uiScrollMessage:hideAllBar(); uiScrollMessage:getInnerContainer():setAutoSize(true) for msgId, msgInfo in pairsByKeys(self.messageList.chatList) do local item = self:createMessageItem(msgId) if item then uiScrollMessage:addChild(item) end end uiScrollMessage:jumpToTopOnSizeChanged() -- 初始化聊天表情 local uiScrollFace = self.ui.Items.ScrollView_Face uiScrollFace:removeAllChildren() uiScrollFace:hideAllBar(); uiScrollFace:getInnerContainer():setAutoSize(true) for k,v in pairsByKeys(self.messageList.faceList) do --ChatDefine.FaceConfigs) do local item = self:createFaceItem(k) if item then uiScrollFace:addChild(item) end end uiScrollFace:jumpToTopOnSizeChanged() -- 初始化聊天 local uiScrollChat = self.ui.Items.ScrollView_Chat uiScrollChat:removeAllChildren() uiScrollChat:hideAllBar(); uiScrollChat:getInnerContainer():setAutoSize(true) -- local texts = { -- {nUserId=nMyUserId,message="按"}, -- {nUserId=nMyUserId,message="按时"}, -- {nUserId=nMyUserId,message="按时按时按时按时按时按时"}, -- {nUserId=nMyUserId,message="按时按时按时按时按时按时按时按时按时按时按时按时按时按时按时按时按时按时"}, -- } -- for k,v in pairsByKeys(texts) do --ChatDefine.FaceConfigs) do -- local item = self:createChatItem(v) -- if item then -- uiScrollChat:addChild(item) -- end -- end uiScrollChat:jumpToTopOnSizeChanged() -- 初始化checkBox的切换 local radio = import("luaScript.Tools.RadioManager"):new() if radio then radio:addItem(self.ui.Items.CheckBox_Message, ChatDefine.MessageType.Message) radio:addItem(self.ui.Items.CheckBox_Face, ChatDefine.MessageType.Face) radio:addItem(self.ui.Items.CheckBox_Chat, ChatDefine.MessageType.Chat) radio:setCallback(handler(self, self.onClickCheckBox)) radio:setDefault(ChatDefine.MessageType.Message) self.messageRadio = radio end if self.showBtn then self:showBtns() else self:hideBtns(); end -- 默认不显示表情选择界面 --self:onClickCloseFace() self.ui.Items.Layout_FaceMenu:setVisible(false) -- 不显示录音动画 self:hideSpeaking() --屏蔽聊天 ljx self.ui.Items.CheckBox_Chat:setVisible(false) self.ui.Items.Button_Send:setVisible(false) self.ui.Items.ImageView_InputBG:setVisible(false) end function ChatView:onLoadMyProp() if not app.php.mypropdata then return end if app.php.mypropdata then for k,v in pairs(app.php.mypropdata) do if v.prop_id and v.prop_id >= 400 and v.prop_id < 500 then self.voicepropid = v.prop_id end if v.prop_id and v.prop_id >= 300 and v.prop_id < 400 then self.messagepropid = v.prop_id end end end end function ChatView:onClickCheckBox(idx) --playBtnEffect() self.ui.Items.ScrollView_Message:setVisible(idx == ChatDefine.MessageType.Message) self.ui.Items.ScrollView_Face:setVisible(idx == ChatDefine.MessageType.Face) self.ui.Items.ScrollView_Chat:setVisible(idx == ChatDefine.MessageType.Chat) end function ChatView:createHeadItem(voiceDir, headPos) local this = self; local uiHead = self.templateHead:getCopied() uiHead.Items = getUIItems(uiHead) uiHead.Items.ImageView_Face:setVisible(false) local szHead = uiHead:getContentSize() local uiVoiceFile, posAnchorVoice, posVoice; local uiMessageFile, posAnchorMessage, posMessage; local winSize = cc.Director:getInstance():getWinSize() local isLeft = headPos.x < winSize.width/2 if not voiceDir then voiceDir = isLeft and ChatDefine.Direction.Left and ChatDefine.Direction.Right end if voiceDir == ChatDefine.Direction.Right then posAnchorVoice = cc.p(0, 0.5) posVoice = cc.p(szHead.width, szHead.height / 2) -- posAnchorMessage = cc.p(0, 0) posMessage = cc.p(szHead.width, 5)--szHead.height / 2) else posAnchorVoice = cc.p(1, 0.5) posVoice = cc.p(0, szHead.height / 2) -- posAnchorMessage = cc.p(1, 0) posMessage = cc.p(0, 5)--szHead.height / 2) end --播放语音动画 uiHead.playVoice = function( timelen ,recordpid, endCallback) if uiHead.uiVoice then uiHead.uiVoice:removeFromParent() uiHead.uiVoice = nil end if voiceDir == ChatDefine.Direction.Right then if recordpid and recordpid > 0 then uiVoiceFile = "res/ui/ui_fangjian/ui_fanjian_voice_left_special.ui" else uiVoiceFile = "res/ui/ui_fangjian/ui_fangjian_voice_left.ui" end else if recordpid and recordpid > 0 then uiVoiceFile = "res/ui/ui_fangjian/ui_fanjian_voice_right_special.ui" else uiVoiceFile = "res/ui/ui_fangjian/ui_fangjian_voice_right.ui" end end local uiVoice = loadUI(uiVoiceFile); if recordpid and recordpid > 0 then uiVoice.Items.ImageView:loadTexture(string.format("res/ui/zy_tongyong/zy_voice/voice/zy_voice_%d.png",recordpid)) end uiVoice.endCallback = endCallback uiVoice.Items = getUIItems(uiVoice) uiVoice.Items.ImageView:playClip("speak") uiVoice.Items.Text:setText(string.format("%d''", timelen)) uiVoice:setAnchorPoint(posAnchorVoice) uiVoice:setPosition(posVoice) uiVoice:runDelay(timelen, function() if uiHead.uiVoice then uiHead.uiVoice:removeFromParent() uiHead.uiVoice = nil end if uiVoice.endCallback then uiVoice.endCallback(); end end) uiHead.uiVoice = uiVoice; uiHead:addChild(uiVoice); end -- 停止语音动画 uiHead.shopVoice = function() if uiHead.uiVoice then if uiHead.uiVoice.endCallback then uiHead.uiVoice.endCallback(); end uiHead.uiVoice.Items.ImageView:stopClip("speak") uiHead.uiVoice:removeFromParent() uiHead.uiVoice = nil end end -- 播放一个表情动画 uiHead.playFace = function(idx, sex) local faceConfig = self.messageList.faceList[idx] if not faceConfig then return end -- 如果有配语音,还要播放对应的语音 local oggFile; if this.isStandardLanguage then oggFile = faceConfig.oggStandard else oggFile = faceConfig.oggLocal end if oggFile and oggFile ~= "" then if string.find(oggFile,"%%s") then --如果需要播放男女音效固定2个%s 例如:mj/res/sound/%s/mj_%s_text_7.ogg oggFile = string.format(oggFile,sex ==1 and "man" or "women",sex) end playVoice(oggFile); end if not faceConfig.aniFile then local nodeFaceImage = uiHead.Items.ImageView_Face nodeFaceImage:loadTexture(faceConfig.btnPng, cc.TextureResType.plistType) local action = cc.Sequence:create(cc.DelayTime:create(2),cc.CallFunc:create(function () nodeFaceImage:setVisible(false) end)) nodeFaceImage:stopAllActions() nodeFaceImage:runAction(action) nodeFaceImage:setVisible(true) return end -- 加载纹理到内存 loadSpriteFrameFile(faceConfig.aniFile) -- 加载第一张图片 local nodeFaceImage = uiHead.Items.ImageView_Face local firstFileName = string.format("face%d_%d.png",idx,1) nodeFaceImage:loadTexture(firstFileName, cc.TextureResType.plistType) -- 循环修改图片 local everyFrame = 0.1 local indexFace = 0 local indexMax = tonumber(faceConfig.frameNum) or 0 local action1 = cc.Sequence:create(cc.DelayTime:create(everyFrame),cc.CallFunc:create(function () indexFace = indexFace + 1 if 0 < indexFace and indexFace <= indexMax then local name = string.format("face%d_%d.png",idx,indexFace) if not tolua.isnull(nodeFaceImage) then nodeFaceImage:loadTexture(name, cc.TextureResType.plistType) end else nodeFaceImage:setVisible(false) end end)) local action2 = cc.Repeat:create(action1, indexMax + 2) nodeFaceImage:stopAllActions() nodeFaceImage:runAction(action2) nodeFaceImage:setVisible(true) end --播放一个快捷语的动画 uiHead.playMessage = function(idx, sex, messagepid) local uiMessageNode = uiHead:getChildByTag(10086) if uiMessageNode then if uiMessageNode.sound then stopVoice(uiMessageNode.sound) end uiHead:removeChildByTag(10086) end local messageConfig = self.messageList.chatList[idx] if messageConfig then if voiceDir == ChatDefine.Direction.Right then if messagepid and messagepid > 0 then uiMessageFile = "res/ui/ui_fangjian/ui_fanjian_message_left_special.ui" else uiMessageFile = "res/ui/ui_fangjian/ui_fangjian_Message_left.ui" end else if messagepid and messagepid > 0 then uiMessageFile = "res/ui/ui_fangjian/ui_fanjian_message_right_special.ui" else uiMessageFile = "res/ui/ui_fangjian/ui_fangjian_Message_right.ui" end end local uiMessage = loadUI(uiMessageFile) uiMessage.Items = getUIItems(uiMessage) if messagepid and messagepid > 0 then uiMessage.Items.ImageView:loadTexture(string.format("res/ui/zy_tongyong/zy_voice/chat/zy_chat_%d.png",messagepid)) uiMessage.Items.ImageView:setCapInsets(MESSAGE_RECT[messagepid]); end if messageConfig.txt then uiMessage.Items.Text_Chat:setText(messageConfig.txt) end -- 添加到头像节点上 -- uiMessage:setAnchorPoint(posAnchorMessage) --uiMessage:setPosition(posMessage) --添加到头像节点上 uiMessage:setPosition(self:getPlayMessagePos(viewId) or posMessage) local textSize = uiMessage.Items.Text_Chat:getContentSize() uiMessage.Items.Layout_Chat:setSize(cc.size(textSize.width+60,textSize.height+44)) if messagepid == 304 then uiMessage.Items.Text_Chat:setTextColor(cc.c4b(255,255,255,255)) end if messagepid and messagepid > 0 then uiMessage.Items.Layout_Chat:setSize(cc.size(textSize.width+94,textSize.height+78)) uiMessage.Items.ImageView:setSize(cc.size(textSize.width+94,textSize.height+78)) end local y = uiHead:getPositionY() + uiMessage.Items.Layout_Chat:getContentSize().height/2 if y>720 then local offsetY = y-720; uiMessage:setPositionY(-offsetY+5) end uiHead:addChild(uiMessage); -- 如果有配语音,还要播放对应的语音 local oggFile; if this.isStandardLanguage then oggFile = messageConfig.oggStandard else oggFile = messageConfig.oggLocal end if oggFile and oggFile ~= "" then if string.find(oggFile,"%%s") then --如果需要播放男女音效固定2个%s 例如:mj/res/sound/%s/mj_%s_text_7.ogg oggFile = string.format(oggFile,sex ==1 and "man" or "women",sex) end playVoice(oggFile); end -- 播放动画,完成后自删 uiMessage.Items.Layout_Chat:playClip("fade", function() uiMessage:removeFromParent() end) end end --播放一个聊天的动画 uiHead.playChat = function(message, messagepid) if voiceDir == ChatDefine.Direction.Right then if messagepid and messagepid > 0 then uiMessageFile = "res/ui/ui_fangjian/ui_fanjian_message_left_special.ui" else uiMessageFile = "res/ui/ui_fangjian/ui_fangjian_Message_left.ui" end else if messagepid and messagepid > 0 then uiMessageFile = "res/ui/ui_fangjian/ui_fanjian_message_right_special.ui" else uiMessageFile = "res/ui/ui_fangjian/ui_fangjian_Message_right.ui" end end local uiMessage = loadUI(uiMessageFile) uiMessage.Items = getUIItems(uiMessage) uiMessage.Items.Text_Chat:setText(message) if messagepid and messagepid > 0 then uiMessage.Items.ImageView:loadTexture(string.format("res/ui/zy_tongyong/zy_voice/chat/zy_chat_%d.png",messagepid)) uiMessage.Items.ImageView:setCapInsets(MESSAGE_RECT[messagepid]); end if messagepid == 304 then uiMessage.Items.Text_Chat:setTextColor(cc.c4b(255,255,255,255)) end -- 添加到头像节点上 -- uiMessage:setAnchorPoint(posAnchorMessage) --uiMessage:setPosition(posMessage) --添加到头像节点上 uiMessage:setPosition(self:getPlayMessagePos(viewId) or posMessage) local textSize = uiMessage.Items.Text_Chat:getContentSize() uiMessage.Items.Layout_Chat:setSize(cc.size(textSize.width+60,textSize.height+44)) if messagepid and messagepid > 0 then uiMessage.Items.Layout_Chat:setSize(cc.size(textSize.width+94,textSize.height+78)) uiMessage.Items.ImageView:setSize(cc.size(textSize.width+94,textSize.height+78)) end local y = uiHead:getPositionY() + uiMessage:getContentSize().height/2 if y>720 then local offsetY = y-720; uiMessage:setPositionY(-offsetY) end uiHead:addChild(uiMessage); -- 播放动画,完成后自删 uiMessage.Items.Layout_Chat:playClip("fade", function() uiMessage:removeFromParent() end) end return uiHead; end -- 创建一个表情按钮的节点 function ChatView:createFaceItem(idx) local ui = self.templateFace:getCopied() ui.Items = getUIItems(ui) local faceConfig = self.messageList.faceList[idx]--ChatDefine.FaceConfigs[idx] if faceConfig then local btnPng = faceConfig.btnPng ui.Items.Button:loadTextureNormal("res/ui/zy_tongyong/zy_face/chat/"..btnPng) ui.Items.Button:loadTexturePressed("res/ui/zy_tongyong/zy_face/chat/"..btnPng) ui.Items.Button:loadTextureDisabled("res/ui/zy_tongyong/zy_face/chat/"..btnPng) end ui.Items.Button:registerClick(function() playBtnEffect() self:sendChatMessage(ChatDefine.MessageType.Face, idx); end) return ui; end -- 创建一个快捷语节点 function ChatView:createMessageItem(idx) local ui = self.templateMessage:getCopied() ui.Items = getUIItems(ui) local messageConfig = self.messageList.chatList[idx] if messageConfig and messageConfig.txt then ui.Items.Text_Message:setText(messageConfig.txt) end ui:registerClick(function() self:sendChatMessage(ChatDefine.MessageType.Message, idx); end) return ui; end -- 创建一个聊天节点 function ChatView:addChatItem(nUserId,message) local userInfo = app.room:getUserInfo(nUserId) userInfo = type(userInfo) == "string" and json.decode(userInfo) or userInfo local childrens = self.ui.Items.ScrollView_Chat:getChildren() if #childrens>=20 then childrens[1]:removeFromParent() end local str = nUserId==app.user.loginInfo.uid and "My" or "Other" local ui = self["templateChat"..str]:getCopied() ui.Items = getUIItems(ui) ui.Items["Text_Chat_"..str]:setText(message) local textSize = ui.Items["Text_Chat_"..str]:getContentSize() ui.Items["Layout_Chat_Text_"..str]:setSize(cc.size(textSize.width+35,textSize.height+35)) ui.Items["Layout_Chat_"..str]:setSize(cc.size(ui.Items["Layout_Chat_"..str]:getContentSize().width,textSize.height+35+35)) local height = ui.Items["Layout_Chat_"..str]:getContentSize().height ui.Items["Layout_Head_"..str]:setPositionY(height-20) ui.Items["Layout_Chat_Text_"..str]:setPositionY(height-20) if userInfo and userInfo.headimgurl then setPlayerHeadImage(nUserId,userInfo.headimgurl,ui.Items["ImageView_Head_"..str],true) end self.ui.Items.ScrollView_Chat:addChild(ui) self.ui.Items.ScrollView_Chat:jumpToBottomOnSizeChanged() return ui end function ChatView:onClickPlayerHead(idx, szHead) playBtnEffect() local nUserId = app.room:getUserIdByViewId(idx) local userInfo = app.room:getUserInfo(nUserId) if nUserId and userInfo then local headPos = self.headInfos[idx].headPos local recordTime = 0 if self.playerVoice[idx] then recordTime = self.playerVoice[idx].recordTime or 0 end local recordCallback = function(uid) self:replayRecord(uid) end local view = import("luaScript.Views.Room.RoomPlayerInfoView"):new(nUserId, userInfo, headPos, szHead, recordTime, recordCallback,self.IDbVisible) view:setAnchorPoint(cc.p(0.5, 0.5)) app:showWaitDialog(view, 0, true) --互斥,点开头像详情后,隐藏一次聊天框 self.ui.Items.Layout_FaceMenu:setVisible(false) --通知游戏Room界面关闭互斥界面 app:dispatchEvent({name = "onCloseRoomMutexView"}); end end --设置隐藏ID function ChatView:setIDVisible(bVisible) self.IDbVisible = bVisible; end -- 打开表情界面 function ChatView:onClickOpenFace() playBtnEffect() self.ui.Items.Layout_FaceMenu:setVisible(not self.ui.Items.Layout_FaceMenu:isVisible()) app:dispatchEvent({name = "onCloseRoomMutexView"}); end -- 关闭表情界面 function ChatView:onClickCloseFace() playBtnEffect() self.ui.Items.Layout_FaceMenu:setVisible(false) end -- 播放表情动画 function ChatView:playFace(seatid, faceId,sex) if self.uiHeads[seatid] then self.uiHeads[seatid].playFace(faceId,sex) end end --播放快捷语动画 function ChatView:playMessage(seatid, chatIdx, sex, messagepid) if self.uiHeads[seatid] then self.uiHeads[seatid].playMessage(chatIdx, sex, messagepid) end end function ChatView:playChat(seatid, message, sex, messagepid) if self.uiHeads[seatid] then self.uiHeads[seatid].playChat(message, messagepid) end end --播放语音动画 function ChatView:playVoice(seatid, timelen, recordpid, endCallback) if self.uiHeads[seatid] then self.uiHeads[seatid].playVoice(timelen, recordpid, endCallback) end end -- function ChatView:shopVoice(seatid) if self.uiHeads[seatid] then self.uiHeads[seatid].shopVoice() end end -- 显示屏幕中间滑动手指取消录音的提示 function ChatView:showSpeaking() logD("ChatView:showSpeaking") self.ui.Items.Layout_luyinzhong:setVisible(true) self.ui.Items.Text_Tips:setText("") if isAndroidPlatform() then self.ui.Items.Layout_luyinzhong:playClip("speaking") elseif isIOSPlatform() then self.ui.Items.Text_Tips:setText("正在开启录音设备") self.ui.Items.Layout_3:setVisible(false); runDelay(1.1, function () logD("ChatView:runDelay") self.ui.Items.Text_Tips:setText("") self.ui.Items.Layout_3:setVisible(true); self.ui.Items.Layout_luyinzhong:playClip("speaking") end) end end -- 隐藏屏幕中间滑动手指取消录音的提示 function ChatView:hideSpeaking() self.ui.Items.Layout_luyinzhong:setVisible(false) self.ui.Items.Layout_luyinzhong:stopClip("speaking") end -- 开始录音 function ChatView:beginRecord() local t = os.time() - self.recordingTime if not app.user:canSendChatMessage(2) or t < ChatDefine.TimeInterval[2] then showTooltip("您发送语音信息的间隔时间太短,请稍后再发!") return end -- 停止所有的表情声音 if self.lastSound then stopVoice(self.lastSound) end --为了不影响录制的过程,还可以听到音效,关闭所有的音效 app.systemSetting.info.sound = false --暂停音乐 cc.AudioController:getInstance():pause(); --暂停音效 --cc.AudioController:getInstance():setPlaySound(false) -- 停止所有的玩家语音 app.plugin:stopPlayRecord() -- 如果有玩家正在说话 if self.lastSpeakingSeatId then self:shopVoice(self.lastSpeakingSeatId) end self.recording = true; self.recordingTime = os.time() --showTooltip("开始录音") self:showSpeaking() app.plugin:startRecord() end -- 开始录音 function ChatView:beginGRecord() local t = os.time() - self.recordingTime if not app.user:canSendChatMessage(2) or t < ChatDefine.TimeInterval[2] then showTooltip("您发送语音信息的间隔时间太短,请稍后再发!") return end -- 停止所有的表情声音 if self.lastSound then stopVoice(self.lastSound) end --为了不影响录制的过程,还可以听到音效,关闭所有的音效 app.systemSetting.info.sound = false --暂停音乐 cc.AudioController:getInstance():pause(); --暂停音效 --cc.AudioController:getInstance():setPlaySound(false) -- 停止所有的玩家语音 app.plugin:stopGPlayRecord() -- 如果有玩家正在说话 if self.lastSpeakingSeatId then self:shopVoice(self.lastSpeakingSeatId) end self.recording = true; self.recordingTime = os.time() --showTooltip("开始录音") self:showSpeaking() app.plugin:startGRecord() end -- 结束录音 function ChatView:stopRecord() if not self.recording then return end -- showTooltip("结束录音111") self.recording = false; self:hideSpeaking(); app.systemSetting.info.sound = self.soundState --继续音乐 cc.AudioController:getInstance():resume(); local recordpropid = tonumber(self.voicepropid) if cc.Application:getInstance():getTargetPlatform() == 0 then local jsonData = { recordUrl = "recordUrl", recordTime = 2, recordpropid = recordpropid, } local content = json.encode(jsonData) if app.user:sendChatMessage(2, content) then -- 记录我发送过的语音 self.playerVoice[self.myViewId] = {} self.playerVoice[self.myViewId].filePath = "" self.playerVoice[self.myViewId].recordUrl = jsonData.recordUrl self.playerVoice[self.myViewId].recordTime = jsonData.recordTime; self.playerVoice[self.myViewId].recordpropid = jsonData.recordpropid -- 播放我的语音 self:_replayRecord(self.myViewId) end return end app.plugin:stopRecord() end -- 结束录音 function ChatView:stopGRecord() if not self.recording then return end -- showTooltip("结束录音111") self.recording = false; self:hideSpeaking(); app.systemSetting.info.sound = self.soundState --继续音乐 cc.AudioController:getInstance():resume(); local recordpropid = tonumber(self.voicepropid) if cc.Application:getInstance():getTargetPlatform() == 0 then local jsonData = { -- recordUrl = "recordUrl", recordUrl = "fileId", recordTime = 2, -- recordpropid = recordpropid, } local content = json.encode(jsonData) if app.user:sendChatMessage(2, content) then -- 记录我发送过的语音 self.playerVoice[self.myViewId] = {} self.playerVoice[self.myViewId].filePath = "" self.playerVoice[self.myViewId].recordUrl = jsonData.recordUrl self.playerVoice[self.myViewId].recordTime = jsonData.recordTime; -- self.playerVoice[self.myViewId].recordpropid = jsonData.recordpropid -- 播放我的语音 self:_replayGRecord(self.myViewId) end return end app.plugin:stopGRecord() end -- 取消录音 function ChatView:cancelRecord() if not self.recording then return end --继续音乐 cc.AudioController:getInstance():resume(); --恢复音效 --cc.AudioController:getInstance():setPlaySound(app.systemSetting.info.sound) app.systemSetting.info.sound = self.soundState --showTooltip("取消录音") self.recording = false; self:hideSpeaking(); app.plugin:cancelRecord() end -- 播放回调函数 function ChatView:recordCallback(event) --恢复音乐 if app.systemSetting.info.music then cc.AudioController:getInstance():resume(); end if not event then return end local filePath, recordUrl, recordTime = event.filePath, event.recordUrl, event.recordTime log("log_event", filePath, recordUrl, recordTime) if not filePath or not recordUrl or not recordTime then return end recordTime = math.ceil(recordTime / 1000); local recordpropid = tonumber(self.voicepropid) --腾讯语音GVoice 开启录音设备大概有1秒延迟 if isIOSPlatform() then recordTime = recordTime - 1; end local jsonData = { recordUrl = recordUrl, recordTime = recordTime, recordpropid = recordpropid, } if recordTime<=1 then showTooltip("录音时间过短!") return end local config=getSubGameConfig(tonumber(app.gameId)) if config and config.belongType==2 then local nMyUserId = app.user.loginInfo.uid self.myViewId = app.room:getViewIdByUserId(nMyUserId) end local content = json.encode(jsonData); if app.user:sendChatMessage(2, content) then -- 记录我发送过的语音 self.playerVoice[self.myViewId] = {} self.playerVoice[self.myViewId].filePath = filePath; self.playerVoice[self.myViewId].recordUrl = recordUrl; self.playerVoice[self.myViewId].recordTime = recordTime; self.playerVoice[self.myViewId].recordpropid = jsonData.recordpropid -- 播放我的语音 self:_replayRecord(self.myViewId) end end -- 播放回调函数 function ChatView:recordGCallback(event) --恢复音乐 if app.systemSetting.info.music then cc.AudioController:getInstance():resume(); end if not event then return end local fileId, filePath, recordTime = event.fileId, event.filePath, event.recordTime log("log_event", fileId, filePath, recordTime) if not fileId or not filePath or not recordTime then return end recordTime = math.ceil(recordTime / 1); -- local recordpropid = tonumber(self.voicepropid) local jsonData = { recordUrl = fileId, recordTime = recordTime, } if recordTime<=1 then showTooltip("录音时间过短!") return end local config=getSubGameConfig(tonumber(app.gameId)) if config and config.belongType==2 then local nMyUserId = app.user.loginInfo.uid self.myViewId = app.room:getViewIdByUserId(nMyUserId) end local content = json.encode(jsonData); if app.user:sendChatMessage(2, content) then -- 记录我发送过的语音 self.playerVoice[self.myViewId] = {} self.playerVoice[self.myViewId].filePath = filePath; self.playerVoice[self.myViewId].recordUrl = fileId; self.playerVoice[self.myViewId].recordTime = recordTime; -- self.playerVoice[self.myViewId].recordpropid = jsonData.recordpropid -- 播放我的语音 self:_replayGRecord(self.myViewId) end end -- 重新播放某个玩家之前说的话,Gvoice function ChatView:_replayGRecord(nSeatShowId) log("ChatView:_replayRecord() nSeatShowId = ", nSeatShowId); log("ChatView:_replayRecord() self.playerVoice = ", table.tostring(self.playerVoice)); local data = self.playerVoice[nSeatShowId] if data then if data.filePath then app.plugin:playGRecord(data.filePath) end local recordTime = data.recordTime local recordpid = data.recordpropid self.lastSpeakingSeatId = nSeatShowId self:playVoice(nSeatShowId, recordTime, recordpid, function() self.lastSpeakingSeatId = nil end) else showTooltip("无历史消息") end end -- 重新播放某个玩家之前说的话 function ChatView:_replayRecord(nSeatShowId) log("ChatView:_replayRecord() nSeatShowId = ", nSeatShowId); log("ChatView:_replayRecord() self.playerVoice = ", table.tostring(self.playerVoice)); local data = self.playerVoice[nSeatShowId] if data then if data.filePath then app.plugin:playRecord(data.filePath) end local recordTime = data.recordTime local recordpid = data.recordpropid self.lastSpeakingSeatId = nSeatShowId self:playVoice(nSeatShowId, recordTime, recordpid, function() self.lastSpeakingSeatId = nil end) else showTooltip("无历史消息") end end function ChatView:sendChatMessage(chatType, chatIdx) if not app.user:canSendChatMessage(chatType) then showTooltip("操作太过频繁,请稍后再发!") return end local nUserSex = app.user.sex==0 and 1 or app.user.sex; local data = { sex = nUserSex, chatIdx = chatIdx, messagepid = self.messagepropid, } -- 发送消息到服务器 --1: 表情 2: 语音 3:聊天 local str = json.encode(data) app.user:sendChatMessage(chatType, str); self:onClickCloseFace() end function ChatView:onChatMessageResponse(event) if not event or not event.response then return end --[[ -- 聊天内容 ChatMessageResponse = defClass("ChatMessageResponse" -- 用户uid , defVar("nUserId", VT_Int, 0) -- //类型 1: 表情 2: 语音 3:聊天 , defVar("type", VT_Short, 0) -- //内容,客户端自定义格式 , defVar("content", VT_String, "") ) --]] local nUserId = event.response.nUserId local chatType = event.response.type local content = event.response.content if not nUserId or not chatType or not content then return end local nSeatShowId = app.room:getViewIdByUserId(nUserId); local data = json.decode(content) if not data then return end -- //类型 1: 表情 2: 语音 3:聊天,4:道具 5:聊天 if chatType == 1 then -- 表情 local sex = data.sex local chatIdx = data.chatIdx self:playFace(nSeatShowId, chatIdx,sex); elseif chatType == 2 then if nUserId == app.user.loginInfo.uid or not self.isVoiceEnabled then -- 如果是我自己发送的录音,在发送之前就已经在播放了,现在不需要再播放一次 或者屏蔽播放语音 return end -- -- 语音 -- local jsonData = json.decode(event.response.content) -- local recordUrl = tostring(jsonData.recordUrl) -- local recordTime = tonumber(jsonData.recordTime) -- local recordpid = tonumber(jsonData.recordpropid) -- -- -- 下载玩家的语音文件并播放 -- -- -- 下载完成后返回该文件在本地存储的路径 -- -- app.plugin:downloadRecord(nUserId, recordUrl, function(recordTag, filePath) -- -- local userId = tonumber(recordTag) -- -- local seatShowId = app.room:getViewIdByUserId(userId) -- -- if not seatShowId or not self.playerVoice[seatShowId] then -- -- print("LHQChatView:onChatMessageResponse() seatShowId = ", seatShowId); -- -- return -- -- end -- -- self.playerVoice[seatShowId].filePath = filePath -- -- end); -- -- 腾讯语音GVoice -- app.plugin:downloadRecord(nUserId, recordUrl, function(recordTag, filePath) -- local userId = tonumber(recordTag) -- local seatShowId = app.room:getViewIdByUserId(userId) -- if not seatShowId or not self.playerVoice[seatShowId] then -- print("LHQChatView:onChatMessageResponse() seatShowId = ", seatShowId); -- return -- end -- self.playerVoice[seatShowId].filePath = filePath -- end); -- -- 记录该玩家的语音文件,重播要用 -- self.playerVoice[nSeatShowId] = {} -- self.playerVoice[nSeatShowId].recordUrl = recordUrl; -- self.playerVoice[nSeatShowId].recordTime = recordTime; -- self.playerVoice[nSeatShowId].recordpropid = recordpid; -- -- 该玩家头像上播放说话的效果 -- self:_replayRecord(nSeatShowId) -- Gvoice begin -- 语音 local jsonData = json.decode(event.response.content) local recordUrl = tostring(jsonData.recordUrl) local recordTime = tonumber(jsonData.recordTime) local recordpid = tonumber(jsonData.recordpropid) -- 腾讯语音GVoice app.plugin:downloadGRecord(nUserId, recordUrl, function( filePath) -- local userId = tonumber(recordTag) local userId = nUserId; local seatShowId = app.room:getViewIdByUserId(userId) if not seatShowId or not self.playerVoice[seatShowId] then print("LHQChatView:onChatMessageResponse() seatShowId = ", seatShowId); return end self.playerVoice[seatShowId].filePath = filePath end); -- 记录该玩家的语音文件,重播要用 self.playerVoice[nSeatShowId] = {} self.playerVoice[nSeatShowId].recordUrl = recordUrl; self.playerVoice[nSeatShowId].recordTime = recordTime; self.playerVoice[nSeatShowId].recordpropid = recordpid; -- 该玩家头像上播放说话的效果 self:_replayRecord(nSeatShowId) -- Gvoice end elseif chatType == 3 then -- 聊天 local sex = data.sex local chatIdx = data.chatIdx local messagepid = data.messagepid self:playMessage(nSeatShowId, chatIdx, sex ,messagepid); elseif chatType == 4 then if not self.isPropEnabled then return end -- 道具 --[[ local data = { propIdx = propIdx, uidSender = uidSender, uidReceiver = uidReceiver, } --]] local propId = data.propIdx local uidSender = data.uidSender local uidReceiver = data.uidReceiver local nViewIdBegin = app.room:getViewIdByUserId(uidSender) local nViewIdEnd = app.room:getViewIdByUserId(uidReceiver) if not nViewIdBegin or not nViewIdEnd or not propId then return end local posBegin = self.headInfos[nViewIdBegin].headPos -- 对自己 == 群发 if uidSender == uidReceiver then local isHave = false -- 首先要搞清楚,房间里面哪些座位是有人的 local viewIds = {} for uid,_ in pairs(self.uids) do local viewId = app.room:getViewIdByUserId(uid) table.insert(viewIds, viewId) end for _, viewId in pairs(viewIds) do if viewId ~= nViewIdBegin then local headInfo = self.headInfos[viewId] if headInfo then isHave = true local posEnd = self.headInfos[viewId].headPos self.propAniPlayer:playAnimationWithPos(posBegin, posEnd, propId) end end end if not isHave then showTooltip("当前没有其他玩家!") end else if self.propAniPlayer then local posEnd = self.headInfos[nViewIdEnd].headPos self.propAniPlayer:playAnimationWithPos(posBegin, posEnd, propId) end end elseif chatType == 5 then local sex = data.sex local content = data.content local messagepid = data.messagepid self:addChatItem(nUserId,content) self:playChat(nSeatShowId, content, sex, messagepid) else showTooltip("未知的聊天消息 "..tostring(chatType)) end end function ChatView:initVoiceTouchEvent() local initPos=cc.p(0,0) local isCancel = false local function onTouchEvent(sender, eventType, touch) logD("ChatView:eventType:"..eventType) if eventType == cc.TouchEventType.began then logD("ChatView:began") isCancel=false initPos=touch:getLocation() self:beginRecord() self:playClip("anxia") -- 点击结束的回调 elseif eventType == cc.TouchEventType.ended then logD("ChatView:ended") -- local currentView = app.currentView -- local buttonName = self:getName() -- local currentViewName = ""; -- if(currentView)then -- currentViewName = currentView.__cname -- end -- if(callbackFunc)then -- callbackFunc(self, eventType, touch); -- end dump(isCancel) if not isCancel then self:stopRecord() end self:playClip("huanyuan") -- 点击取消的回调 elseif eventType == cc.TouchEventType.moved then -- logD("ChatView:moved") -- local curPos=touch:getLocation() -- -- local delta=touch:getDelta() -- if math.abs(curPos.x-initPos.x)>20 or math.abs(curPos.y-initPos.y)>20 then -- isCancel=true -- self:cancelRecord() -- end elseif eventType == cc.TouchEventType.canceled then logD("ChatView:canceled") -- if(clickCancelFunc)then -- clickCancelFunc(self); -- end isCancel=true self:stopRecord() self:playClip("huanyuan") end return true; end self.ui.Items.Button_Voice:addTouchEventListener(onTouchEvent) end function ChatView:onChangeYinXiao(data) self.soundState = app.systemSetting.info.sound end function ChatView:onClickSend() if not app.user:canSendChatMessage(ChatDefine.MessageType.Chat) then showTooltip("您发送信息的间隔时间太短,请稍后再发!") return end local content = self.ui.Items.TextField_Input:getString() if not content or content=="" then return end self.ui.Items.TextField_Input:setText("") local nUserSex = app.user.sex==0 and 1 or app.user.sex; local data = { sex = nUserSex, content = content, messagepid = self.messagepropid, } -- 发送消息到服务器 --1: 表情 2: 语音 3:聊天 local str = json.encode(data) app.user:sendChatMessage(ChatDefine.MessageType.Chat, str) self:onClickCloseFace() -- self.messageRadio:setDefault(ChatDefine.MessageType.Chat) end --- 显示/隐藏常用聊天语按钮 function ChatView:setBtnFaceVisible(isVisible) self.ui.Items.Button_Face:setVisible(isVisible) end --- 显示/隐藏语音按钮 function ChatView:setBtnVoiceVisible(isVisible) self.ui.Items.Button_Voice:setVisible(isVisible) end function ChatView:setPlayMessagePos(pos) self.playMessagePos = pos end function ChatView:getPlayMessagePos(idx) if self.playMessagePos then return self.playMessagePos[idx] end return nil end return ChatView;