|
- -- 聊天组件 配合RoomChatView使用
-
- local ChatDefine = require("luaScript.GameChatDefine")
-
- local RoomChatComponentView = class("RoomChatComponentView", cc.UIView)
-
- function RoomChatComponentView:ctor(heads,messageList,faceList)
- RoomChatComponentView.super.ctor(self)
-
- --头像节点 viewId 对应下标
- -- {
- -- [1]= headNode,
- -- }
- self.heads = heads or {}
-
- --定义处理消息函数
- self.handlers = {
- [ChatDefine.MessageType.Face] = handler(self,self.onFaceHandler),
- [ChatDefine.MessageType.Voice] = handler(self,self.onVoiceHandler),
- [ChatDefine.MessageType.Message] = handler(self,self.onMessageHandler),
- [ChatDefine.MessageType.Prop] = handler(self,self.onPropHandler),
- [ChatDefine.MessageType.Chat] = handler(self,self.onChatHandler),
- }
-
- -- 道具播放器
- self.propAniPlayer = import("luaScript.Tools.PropAniPlayer"):new(self)
-
-
- self.messageList = messageList or {
- [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 = "等下再来一把!"},
- }
- self.faceList = faceList or ChatDefine.FaceConfigs
-
- --聊天记录
- self.chatRecord = {}
-
- --语音是否播放
- self.isVoiceEnabled = true
-
- --是否显示道具动画
- self.isPropEnabled = true
-
- -- 是否说普通话
- self.isStandardLanguage = true
- end
-
- -- 设置是否说普通话
- function RoomChatComponentView:setLanguage(isStandard)
- self.isStandardLanguage = isStandard
- end
-
- function RoomChatComponentView:setPropEnabled(enable)
- self.isPropEnabled = enable
- end
-
- function RoomChatComponentView:setVoiceEnabled(enable)
- self.isVoiceEnabled = enable
- end
-
- function RoomChatComponentView:onEnter()
- RoomChatComponentView.super.onEnter(self)
- self:initBindEvent()
- end
-
- function RoomChatComponentView:initBindEvent()
- -- 监听服务器下发的聊天事件
- self:bindEvent(app.user, "onChatMessageResponse", handler(self, self.onChatMessageResponse))
- --聊天界面获取聊天记录
- self:bindEvent(app.user, GAME_EVENT.CHAT_GET_RECORED, handler(self, self.onGetRecordEvent))
-
- self:bindEvent(app.user, GAME_EVENT.CHAT_PLAY_VOICE, handler(self, self.onPlayVoiceEvent))
-
- self:bindEvent(app.user, GAME_EVENT.CHAT_STOP_VOICE, handler(self, self.onStopVoiceEvent))
-
- end
-
- function RoomChatComponentView: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 viewId = app.room:getViewIdByUserId(nUserId)
-
- local data = json.decode(content)
- if not data then
- return
- end
-
- if self.handlers[chatType] then
- self.handlers[chatType](nUserId,viewId,data)
- end
-
- end
-
- --表情
- function RoomChatComponentView:onFaceHandler(nUserId,viewId,data)
- local sex = data.sex
- local idx = data.chatIdx
- local faceConfig = self.faceList[idx]
- if not faceConfig or not self.heads[viewId] then
- return
- end
-
- -- 如果有配语音,还要播放对应的语音
- local oggFile;
- if self.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
-
- local headSize = self.heads[viewId]:getContentSize()
-
- if not faceConfig.aniFile then
- local nodeFaceImage = cc.ImageView:createNode()
- nodeFaceImage:loadTexture(faceConfig.btnPng, cc.TextureResType.plistType)
- local action = cc.Sequence:create(cc.DelayTime:create(2),cc.RemoveSelf:create())
- nodeFaceImage:runAction(action)
- self.heads[viewId]:addChild(nodeFaceImage)
- nodeFaceImage:setPosition(headSize.width/2,headSize.height/2)
- return
- end
-
- -- 加载纹理到内存
- loadSpriteFrameFile(faceConfig.aniFile)
-
- -- 加载第一张图片
- local sprite = cc.Sprite:createWithSpriteFrameName(string.format("face%d_%d.png",idx,1))
- local animation = cc.SpriteAnimation:create()
- for i = 1,faceConfig.frameNum do
- local frame = cc.SpriteFrameCache:getInstance():getSpriteFrameByName(string.format("face%d_%d.png",idx,i))
- animation:addSpriteFrame(frame)
- end
- animation:setDelayPerUnit(0.1)
- sprite:runAction(cc.Sequence:create(cc.SpriteAnimate:create(animation),cc.RemoveSelf:create()))
- self.heads[viewId]:addChild(sprite)
- sprite:setScale(0.6)
- sprite:setPosition(headSize.width/2,headSize.height/2)
- end
-
-
- function RoomChatComponentView:showMessage(viewId,content)
- if not self.heads[viewId] then
- return
- end
- local headPos = self.heads[viewId]:getWorldPosition()
- local headSize = self.heads[viewId]:getContentSize()
- local size = self:getContentSize()
-
- local uiMessageFile = ""
- local posMessage = cc.p(0,0)
- if headPos.x<size.width/2 then
- uiMessageFile = "res/ui/ui_fangjian/ui_fangjian_Message_left.ui"
- posMessage = cc.p(headSize.width, 5)
- else
- uiMessageFile = "res/ui/ui_fangjian/ui_fangjian_Message_right.ui"
- posMessage = cc.p(0, 5)
- end
-
- local uiMessage = loadUI(uiMessageFile)
- uiMessage.Items = getUIItems(uiMessage)
- if content then
- uiMessage.Items.Text_Chat:setText(content)
- end
-
- uiMessage:setPosition(posMessage)
-
- local textSize = uiMessage.Items.Text_Chat:getContentSize()
- uiMessage.Items.Layout_Chat:setSize(cc.size(textSize.width+60,textSize.height+44))
-
- local y = headPos.y + uiMessage.Items.Layout_Chat:getContentSize().height/2
- if y>size.height then
- local offsetY = y-size.height;
- uiMessage:setPositionY(-offsetY-5)
- end
- self.heads[viewId]:addChild(uiMessage)
-
- -- 播放动画,完成后自删
- uiMessage.Items.Layout_Chat:playClip("fade", function()
- uiMessage:removeFromParent()
- end)
- end
-
- --短语
- function RoomChatComponentView:onMessageHandler(nUserId,viewId,data)
- local sex = data.sex
- local idx = data.chatIdx
- local messageConfig = self.messageList[idx]
- if not messageConfig then
- return
- end
- self:showMessage(viewId,messageConfig.txt)
-
- -- 如果有配语音,还要播放对应的语音
- local oggFile;
- if self.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
- end
-
- --聊天
- function RoomChatComponentView:onChatHandler(nUserId,viewId,data)
- local content = data.content
- if #self.chatRecord>=20 then
- table.remove(self.chatRecord,1)
- end
- table.insert(self.chatRecord,{nUserId=nUserId,content=content})
- app.user:dispatchEvent({name = GAME_EVENT.CHAT_PRSPONSE , nUserId = nUserId, content = content})
-
- self:showMessage(viewId,content)
- end
-
- function RoomChatComponentView:showVoice(viewId,timelen)
- if not self.heads[viewId] then
- return
- end
- local uiHead = self.heads[viewId]
-
- if uiHead.uiVoice and not tolua.isnull(uiHead.uiVoice) then
- uiHead.uiVoice:removeFromParent()
- uiHead.uiVoice = nil
- end
- local headPos = uiHead:getWorldPosition()
- local headSize = uiHead:getContentSize()
- local size = self:getContentSize()
-
- local uiVoiceFile, posAnchorVoice, posVoice
- if headPos.x<size.width/2 then
- uiVoiceFile = "res/ui/ui_fangjian/ui_fangjian_voice_left.ui"
- posAnchorVoice = cc.p(0, 0.5)
- posVoice = cc.p(headSize.width, headSize.height / 2)
- else
- uiVoiceFile = "res/ui/ui_fangjian/ui_fangjian_voice_right.ui"
- posAnchorVoice = cc.p(1, 0.5)
- posVoice = cc.p(0, headSize.height / 2)
- end
-
- local uiVoice = loadUI(uiVoiceFile);
- 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 and not tolua.isnull(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
-
- function RoomChatComponentView:hideVoice(viewId)
- if not self.heads[viewId] then
- return
- end
- local uiHead = self.heads[viewId]
-
- if uiHead.uiVoice and not tolua.isnull(uiHead.uiVoice) then
- uiHead.uiVoice:removeFromParent()
- uiHead.uiVoice = nil
- end
- end
-
- --语音
- function RoomChatComponentView:onVoiceHandler(nUserId,viewId,data)
- local recordUrl = tostring(data.recordUrl)
- local recordTime = tonumber(data.recordTime)
- if nUserId == app.user.loginInfo.uid or not self.isVoiceEnabled then
- -- 如果是我自己发送的录音,在发送之前就已经在播放了,现在不需要再播放一次 或者屏蔽播放语音
- return
- end
- app.user:dispatchEvent({name = GAME_EVENT.CHAT_VOICE_RESP ,nUserId = nUserId,viewId = viewId, recordUrl = recordUrl, recordTime = recordTime})
- -- self:showVoice(viewId,recordTime)
- end
-
- --道具
- function RoomChatComponentView:onPropHandler(nUserId,viewId,data)
- if not self.isPropEnabled then
- return
- end
-
- 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.heads[nViewIdBegin]:getWorldPosition()
-
- -- 对自己 == 群发
- if uidSender == uidReceiver then
- -- 首先要搞清楚,房间里面哪些座位是有人的
- -- local viewIds = {}
- -- for uid,_ in pairs(self.uids) do
- -- local viewId = app.room:getViewIdByUserId(uid)
- -- table.insert(viewIds, viewId)
- -- end
- local isHave = false
- for viewId, head in pairs(self.heads) do
- if viewId ~= nViewIdBegin then
- local uid = app.room:getUserIdByViewId(viewId)--self.headInfos[viewId]
- if uid then --如果座位上有人 则播放
- isHave = true
- local posEnd = head:getWorldPosition()
- self.propAniPlayer:playAnimationWithPos(posBegin, posEnd, propId)
- end
- end
- end
- if not isHave then
- showTooltip("当前没有其他玩家!")
- end
- else
- if self.propAniPlayer and self.heads[nViewIdEnd] then
- local posEnd = self.heads[nViewIdEnd]:getWorldPosition()
- self.propAniPlayer:playAnimationWithPos(posBegin, posEnd, propId)
- end
- end
- end
-
- --获取聊天记录事件
- function RoomChatComponentView:onGetRecordEvent()
- app.user:dispatchEvent({name = GAME_EVENT.CHAT_GET_RECORED_RESP , messages = self.chatRecord})
- end
-
-
- function RoomChatComponentView:onPlayVoiceEvent(event)
- self:showVoice(event.viewId,event.recordTime)
- end
-
- function RoomChatComponentView:onStopVoiceEvent(event)
- self:hideVoice(event.viewId)
- end
-
-
- return RoomChatComponentView
|