You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

642 rivejä
18 KiB

  1. -- 主界面
  2. -- 加载界面时,分别在五个玩家门前放置5张牌,但并不显示
  3. -- 更新玩家手牌列表时,按需显示
  4. local MJDefine = MJFramework.MJImport("mj.luaScript.MJDefine")
  5. local MJSound=MJFramework.MJImport("mj.luaScript.MJSound")
  6. local MJChatFaceView=MJFramework.MJImport("mj.luaScript.Views.Room.MJChatFaceView")
  7. local MJRoomMessageView = class("MJRoomMessageView", cc.UIView)
  8. function MJRoomMessageView:ctor(ui)
  9. MJRoomMessageView.super.ctor(self);
  10. -- 玩家节点
  11. self.nodes = {}
  12. self.recording = false; -- 是否正在录音
  13. --是否关闭点击信息
  14. self.m_isClose = true
  15. -- 记录每个玩家的最后一条语音
  16. self.playerVoice = {}
  17. --[[
  18. self.playerVoice =
  19. {
  20. [1] = {url = url, filePath = filePath, recordTime = recordTime},
  21. [2] = {url = url, filePath = filePath, recordTime = recordTime},
  22. [3] = {url = url, filePath = filePath, recordTime = recordTime},
  23. [4] = {url = url, filePath = filePath, recordTime = recordTime},
  24. [5] = {url = url, filePath = filePath, recordTime = recordTime},
  25. }
  26. --]]
  27. -- 最后一条音效
  28. self.lastSound = nil
  29. -- 正在说话的椅子号(同一时刻只允许一个玩家说话)
  30. self.lastSpeakingSeatId = false
  31. end
  32. function MJRoomMessageView:loadUI()
  33. local ui = loadUI("mj/res/ui/ui_fangjian/mj_ui_shengyin.ui");
  34. self.ui = ui;
  35. self:addChild(ui);
  36. end
  37. function MJRoomMessageView:onEnter()
  38. MJRoomMessageView.super.onEnter(self)
  39. self:loadUI()
  40. -- 语音按钮
  41. self.ui.Items.Button_Record:registerClick(handler(self , self.stopRecord), handler(self , self.beginRecord), handler(self , self.cancelRecord));
  42. -- 如果没有语音插件,则不显示语音按钮
  43. if not app.plugin.pluginVoice then
  44. self.ui.Items.Button_Record:setVisible(false)
  45. end
  46. -- 表情按钮
  47. self.ui.Items.Button_Face:registerClick(handler(self , self.onClickFace))
  48. -- 录音中
  49. self.ui.Items.Layout_luyinzhong:setVisible(false)
  50. -- 初始化玩家的各种节点
  51. self:initNodes()
  52. -- 监听事件
  53. self:initEvents()
  54. --加载表情图片
  55. cc.SpriteFrameCache:getInstance():addSpriteFramesWithFile("mj/res/ui/zy_fangjian/mj_face.plist")
  56. end
  57. function MJRoomMessageView:initNodes()
  58. self.myViewId = MJDefine.MyViewId--LHQ_GAME_CONST.GAME_CONST_ME_VIEW_ID
  59. for i = 1, 4 do
  60. self.nodes[i] = {}
  61. local nodes = self.nodes[i];
  62. -- 说话的语音
  63. local nameSpeak = string.format("Layout_speak_%d",i)
  64. local nodeSpeak = self.ui.Items[nameSpeak]
  65. nodeSpeak:setVisible(false)
  66. nodes.nodeSpeak = nodeSpeak;
  67. -- 玩家头像信息
  68. -- local nameHeadInfo = string.format("Layout_wanjiaxinxi_%d",i)
  69. -- local nodeHeadInfo = self.ui.Items[nameHeadInfo]
  70. -- nodeHeadInfo:setVisible(false)
  71. -- nodes.nodeHeadInfo = nodeHeadInfo;
  72. --表情
  73. local nameFaceBG = string.format("Layout_face_%d",i);
  74. local nodeFaceBG = self.ui.Items[nameFaceBG]
  75. nodeFaceBG:setVisible(false)
  76. nodes.nodeFaceBG = nodeFaceBG;
  77. --表情图片
  78. local nameFaceImage = string.format("ImageView_face_%d",i);
  79. local nodeFaceImage = self.ui.Items[nameFaceImage]
  80. nodeFaceImage:setVisible(false)
  81. nodes.nodeFaceImage = nodeFaceImage;
  82. --聊天文字
  83. local nameChatText = string.format("Text_Chat_%d",i);
  84. local nodeChatText = self.ui.Items[nameChatText]
  85. nodes.nodeChatText = nodeChatText;
  86. end
  87. end
  88. function MJRoomMessageView:ReplayPlayerVoice(event)
  89. local nSeatShowId=app.room:getViewIdByUserId(event.nUserId)
  90. -- self:replayRecord(viewId)
  91. if self.playerVoice[nSeatShowId] then
  92. local recordTime=self.playerVoice[nSeatShowId].recordTime
  93. --停止播放背景音乐
  94. cc.AudioController:getInstance():pause()
  95. --系统的音效状态
  96. -- self.soundState = app.systemSetting.info.sound
  97. --为了不影响录制的过程,还可以听到音效,关闭所有的音效
  98. app.systemSetting.info.sound = false
  99. --停止播放音效
  100. --cc.AudioController:getInstance():setPlaySound(false)
  101. -- 播放语音
  102. self:replayRecord(nSeatShowId)
  103. --必须用全局的
  104. local seq = cc.Sequence:create(cc.DelayTime:create(recordTime),cc.CallFunc:create(function ()
  105. cc.AudioController:getInstance():resume()
  106. app.systemSetting:resetEffect()
  107. -- app.systemSetting.info.sound = self.soundState
  108. --恢复音效
  109. --cc.AudioController:getInstance():setPlaySound(app.systemSetting.info.sound)
  110. end))
  111. cc.Director:getInstance():getRunningScene():runAction(seq)
  112. else
  113. if nSeatShowId == self.myViewId then
  114. showTooltip("请先录音哦")
  115. else
  116. showTooltip("该玩家还没说过话呢")
  117. end
  118. end
  119. end
  120. function MJRoomMessageView:initEvents()
  121. -- 玩家语音
  122. self:bindEvent(app.user , "onChatMessageResponse" , handler(self , self.onChatMessageResponse));
  123. -- 回调語音播放
  124. self:bindEvent(app , "recordCallback" , handler(self , self.recordCallback));
  125. -- 重播語音播放
  126. self:bindEvent(app.room , MJDefine.MJEvent.ReplayPlayerVoice , handler(self , self.ReplayPlayerVoice));
  127. end
  128. -- function MJRoomMessageView:onClickBG()
  129. -- -- 隐藏头像
  130. -- for i = 1, LHQ_GAME_CONST.LHQ_GAME_CONST_PLAYER do
  131. -- self.nodes[i].nodeHeadInfo:setVisible(false)
  132. -- self.nodes[i].nodeHeadInfo:removeAllChildren()
  133. -- end
  134. -- self.m_isClose = true
  135. -- end
  136. -- 显示屏幕中间滑动手指取消录音的提示
  137. function MJRoomMessageView:showSpeaking()
  138. self.ui.Items.Layout_luyinzhong:setVisible(true)
  139. self.ui.Items.Layout_luyinzhong:playClip("speaking")
  140. end
  141. -- 隐藏屏幕中间滑动手指取消录音的提示
  142. function MJRoomMessageView:hideSpeaking()
  143. self.ui.Items.Layout_luyinzhong:setVisible(false)
  144. self.ui.Items.Layout_luyinzhong:stopClip("speaking")
  145. end
  146. function MJRoomMessageView:beginRecord()
  147. -- if not app.plugin:checkRecorderPermission() then
  148. -- showTooltip("没有获取语音权限!请检查手机设置!")
  149. -- return
  150. -- end
  151. if not app.user:canSendChatMessage(2) then
  152. showTooltip("您发送语音信息的间隔时间太短,请稍后再发!")
  153. return
  154. end
  155. -- 停止所有的表情声音
  156. if self.lastSound then
  157. stopVoice(self.lastSound)
  158. end
  159. --系统的音效状态
  160. -- self.soundState = app.systemSetting.info.sound
  161. --为了不影响录制的过程,还可以听到音效,关闭所有的音效
  162. app.systemSetting.info.sound = false
  163. --暂停音乐
  164. cc.AudioController:getInstance():pause();
  165. --暂停音效
  166. --cc.AudioController:getInstance():setPlaySound(false)
  167. -- 停止所有的玩家语音
  168. app.plugin:stopPlayRecord()
  169. -- 如果有玩家正在说话
  170. if self.lastSpeakingSeatId then
  171. self.nodes[self.lastSpeakingSeatId].nodeSpeak:setVisible(false)
  172. end
  173. self.recording = true;
  174. --showTooltip("开始录音")
  175. self:showSpeaking()
  176. app.plugin:startRecord()
  177. end
  178. function MJRoomMessageView:cancelRecord()
  179. if not self.recording then
  180. return
  181. end
  182. --继续音乐
  183. cc.AudioController:getInstance():resume();
  184. --恢复音效
  185. --cc.AudioController:getInstance():setPlaySound(app.systemSetting.info.sound)
  186. --showTooltip("取消录音")
  187. self.recording = false;
  188. self:hideSpeaking();
  189. app.plugin:cancelRecord()
  190. end
  191. function MJRoomMessageView:stopRecord()
  192. if not self.recording then
  193. return
  194. end
  195. --showTooltip("结束录音")
  196. self.recording = false;
  197. self:hideSpeaking();
  198. app.systemSetting:resetEffect()
  199. -- app.systemSetting.info.sound = self.soundState
  200. --继续音乐
  201. cc.AudioController:getInstance():resume();
  202. --恢复音效
  203. --cc.AudioController:getInstance():setPlaySound(app.systemSetting.info.sound)
  204. if cc.Application:getInstance():getTargetPlatform() == 0 then
  205. local jsonData =
  206. {
  207. recordUrl = "recordUrl",
  208. recordTime = 10,
  209. }
  210. local content = json.encode(jsonData)
  211. if app.user:sendChatMessage(2, content) then
  212. -- 记录我发送过的语音
  213. self.playerVoice[self.myViewId] = {}
  214. self.playerVoice[self.myViewId].filePath = ""
  215. self.playerVoice[self.myViewId].recordUrl = jsonData.recordUrl
  216. self.playerVoice[self.myViewId].recordTime = jsonData.recordTime;
  217. --播放录音时先停止背景音乐
  218. --cc.AudioController:getInstance():pause();
  219. -- 播放我的语音
  220. self:replayRecord(self.myViewId)
  221. -- 播放我的语音
  222. self:showSpeakClip(self.myViewId)
  223. self.ui.Items.Layout_1:runDelay(jsonData.recordTime, function()
  224. --播放背景音乐
  225. --cc.AudioController:getInstance():resume();
  226. end )
  227. end
  228. return
  229. end
  230. app.plugin:stopRecord()
  231. end
  232. -- 播放回调函数
  233. function MJRoomMessageView:recordCallback(event)
  234. --恢复音乐
  235. if app.systemSetting.info.music then
  236. cc.AudioController:getInstance():resume();
  237. end
  238. if not event then return end
  239. local filePath, recordUrl, recordTime = event.filePath, event.recordUrl, event.recordTime
  240. log("log_event", filePath, recordUrl, recordTime)
  241. if not filePath then return end
  242. if not recordUrl then return end
  243. if not recordTime then return end
  244. recordTime = math.ceil(recordTime / 1000);
  245. local jsonData =
  246. {
  247. recordUrl = recordUrl,
  248. recordTime = recordTime,
  249. }
  250. if recordTime<=1 then
  251. showTooltip("录音时间过短!")
  252. return
  253. end
  254. local content = json.encode(jsonData);
  255. if app.user:sendChatMessage(2, content) then
  256. -- 记录我发送过的语音
  257. self.playerVoice[self.myViewId] = {}
  258. self.playerVoice[self.myViewId].filePath = filePath;
  259. self.playerVoice[self.myViewId].recordUrl = recordUrl;
  260. self.playerVoice[self.myViewId].recordTime = recordTime;
  261. --播放录音时先停止背景音乐
  262. --cc.AudioController:getInstance():pause();
  263. -- 播放我的语音
  264. self:replayRecord(self.myViewId)
  265. -- 播放我的语音
  266. self:showSpeakClip(self.myViewId)
  267. -- self.ui.Items.Layout_1:runDelay(recordTime, function()
  268. -- --播放背景音乐
  269. -- cc.AudioController:getInstance():resume();
  270. -- end)
  271. end
  272. end
  273. -- 重新播放某个玩家之前说的话
  274. function MJRoomMessageView:replayRecord(nSeatShowId)
  275. log("MJRoomMessageView:replayRecord() nSeatShowId = ", nSeatShowId);
  276. log("MJRoomMessageView:replayRecord() self.playerVoice = ", table.tostring(self.playerVoice));
  277. local data = self.playerVoice[nSeatShowId]
  278. if data and data.filePath then
  279. app.plugin:playRecord(data.filePath)
  280. local recordTime = data.recordTime
  281. self.lastSpeakingSeatId = nSeatShowId
  282. self.ui.Items.Layout_1:runDelay(recordTime, function()
  283. self.lastSpeakingSeatId = nil
  284. end )
  285. end
  286. end
  287. -- 播放某个玩家说话的动画
  288. function MJRoomMessageView:showSpeakClip(nSeatShowId)
  289. if not self.playerVoice[nSeatShowId] then
  290. return
  291. end
  292. local recordTime = self.playerVoice[nSeatShowId].recordTime or 1
  293. local uiFile = ""
  294. if nSeatShowId == 1 or nSeatShowId == 2 then
  295. uiFile = "res/ui/ui_fangjian/ui_fangjian_speak_4.ui"
  296. else
  297. uiFile = "res/ui/ui_fangjian/ui_fangjian_speak_2.ui"
  298. end
  299. local ui = loadUI(uiFile)
  300. ui.Items.Text:setText(tostring(recordTime).."''");
  301. ui.Items.ImageView:playClip("speak");
  302. local nodeSpeak = self.nodes[nSeatShowId].nodeSpeak;
  303. nodeSpeak:removeAllChildren()
  304. nodeSpeak:addChild(ui);
  305. nodeSpeak:setVisible(true)
  306. -- self.soundState = app.systemSetting.info.sound
  307. --播放录音时先停止背景音乐
  308. cc.AudioController:getInstance():pause();
  309. app.systemSetting.info.sound = false
  310. nodeSpeak:runDelay(recordTime, function()
  311. nodeSpeak:setVisible(false)
  312. nodeSpeak:removeAllChildren()
  313. --播放背景音乐
  314. cc.AudioController:getInstance():resume();
  315. app.systemSetting:resetEffect()
  316. -- app.systemSetting.info.sound = self.soundState
  317. end )
  318. -- 记录语音正在播放中
  319. self.lastSpeakingSeatId = nSeatShowId
  320. self.ui:runDelay(recordTime, function()
  321. self.lastSpeakingSeatId = nil
  322. end )
  323. end
  324. --点击表情按钮显示表情界面
  325. function MJRoomMessageView:onClickFace()
  326. local function SendChatMessage(chatId,mType)
  327. if not app.user:canSendChatMessage(1) then
  328. showTooltip("您发送聊天信息的间隔时间太短,请稍后再发!")
  329. return
  330. end
  331. local sexId = 0
  332. local memberInfo = app.room.roomInfo.memberList[app.user.loginInfo.uid]
  333. if memberInfo then
  334. local userInfo = json.decode(memberInfo.userInfo)
  335. if not userInfo then
  336. return
  337. end
  338. --男1女2,默认是男生
  339. sexId = tonumber(userInfo.sex) or 1
  340. end
  341. local data =
  342. {
  343. Id = chatId,
  344. sexId = sexId,
  345. }
  346. -- 发送消息到服务器
  347. --1: 表情 2: 语音 3:聊天
  348. local str = json.encode(data)
  349. local isSendSuccess = app.user:sendChatMessage(mType, str);
  350. if isSendSuccess == true then
  351. -- 本地播放表情和音效
  352. if mType == 1 then
  353. --self:showFace(self.myViewId, chatId);
  354. elseif mType == 3 then
  355. --self:showChat(self.myViewId, chatId,sexId);
  356. end
  357. end
  358. end
  359. playBtnEffect()
  360. local function mesCallBack(idx)
  361. playBtnEffect()
  362. SendChatMessage(idx,3)
  363. end
  364. local function faceCallBack(idx)
  365. playBtnEffect()
  366. SendChatMessage(idx,1)
  367. end
  368. local faceUI = MJChatFaceView:new(MJDefine.MJGameChatTxt,mesCallBack,faceCallBack)
  369. self:getParent():addChild(faceUI,1);
  370. end
  371. --显示快捷语
  372. function MJRoomMessageView:showChat(nSeatShowId, Id,sex)
  373. -- local voiceFile = ""
  374. -- if sexId == 1 then
  375. -- -- voiceFile = string.format("resLiuHuQiang/sound/chat/lhq_%s_%d.ogg","male",Id)
  376. -- else
  377. -- -- voiceFile = string.format("resLiuHuQiang/sound/chat/lhq_%s_%d.ogg","female",Id)
  378. -- end
  379. --播放音效
  380. MJSound.PlayTextSound(sex,Id)
  381. -- self:playFaceVoice(voiceFile);
  382. --展示话筒
  383. self.nodes[nSeatShowId].nodeChatText:setText(MJDefine.MJGameChatTxt[Id])
  384. self.nodes[nSeatShowId].nodeFaceBG:setScale(0,0,0)
  385. self.nodes[nSeatShowId].nodeFaceBG:setOpacity(255)
  386. self.nodes[nSeatShowId].nodeFaceBG:setVisible(true)
  387. self.nodes[nSeatShowId].nodeFaceBG:stopAllActions()
  388. self.nodes[nSeatShowId].nodeFaceBG:runAction(cc.Sequence:create(cc.ScaleTo:create(0.2,1,1,1),
  389. cc.DelayTime:create(4.0),cc.FadeOut:create(0.3),cc.CallFunc:create(function ()
  390. self.nodes[nSeatShowId].nodeFaceBG:setVisible(false)
  391. self.nodes[nSeatShowId].nodeFaceBG:setOpacity(255)
  392. end)))
  393. end
  394. --显示表情
  395. function MJRoomMessageView:showFace(nSeatShowId, Id, sex)
  396. --播放音效
  397. MJSound.PlayFaceSound(sex,Id)
  398. --播放动画
  399. -- self:playFaceAnimation(nSeatShowId,Id)
  400. -- local face=cc.Sprite:createWithSpriteFrameName("mj_face_"..Id..".png")
  401. local nodeFaceImage = self.nodes[nSeatShowId].nodeFaceImage
  402. local name = string.format("mj_face_%d.png",Id,Id)
  403. if not tolua.isnull(nodeFaceImage) then
  404. nodeFaceImage:setVisible(true)
  405. nodeFaceImage:loadTexture(name, cc.TextureResType.plistType)
  406. nodeFaceImage:stopAllActions()
  407. local seq = cc.Sequence:create(cc.DelayTime:create(2),cc.CallFunc:create(function ()
  408. nodeFaceImage:setVisible(false)
  409. end))
  410. nodeFaceImage:runAction(seq)
  411. end
  412. end
  413. function MJRoomMessageView:playFaceAnimation(nSeatShowId,Id)
  414. --判断纹理是否存在
  415. local name = string.format("face%d_%d.png",Id,1)
  416. local cache = cc.SpriteFrameCache:getInstance()
  417. local spriteFrame = cache:getSpriteFrameByName(name);
  418. if tolua.isnull(spriteFrame) then
  419. print("spriteFrame is not in cache")
  420. return
  421. end
  422. local nodeFaceImage = self.nodes[nSeatShowId].nodeFaceImage
  423. nodeFaceImage:setScale(0.6)
  424. local indexFace = 0; --[1-10]
  425. local maxList = {10,10,10,10,10,10,10,24,10,12,11,10}
  426. --每隔多少秒切换一张图片
  427. local everyFrame = 0.1
  428. local seq = cc.Sequence:create(cc.DelayTime:create(everyFrame),cc.CallFunc:create(function ()
  429. indexFace = indexFace + 1
  430. if 0 < indexFace and indexFace <= maxList[Id] then
  431. local name = string.format("face%d_%d.png",Id,indexFace)
  432. if not tolua.isnull(nodeFaceImage) then
  433. nodeFaceImage:loadTexture(name, cc.TextureResType.plistType)
  434. end
  435. else
  436. self.nodes[nSeatShowId].nodeFaceImage:setVisible(false)
  437. end
  438. end))
  439. if not maxList[Id] then
  440. return
  441. end
  442. local act = cc.Repeat:create(seq,maxList[Id] + 2)
  443. nodeFaceImage:stopAllActions()
  444. nodeFaceImage:runAction(act)
  445. nodeFaceImage:setVisible(true)
  446. end
  447. --播放表情音效
  448. function MJRoomMessageView:playFaceVoice(musicFilePath)
  449. -- 如果正在播放语音,则不处理
  450. if self.lastSpeakingSeatId then
  451. return
  452. end
  453. -- 如果正在播放音效,则停止音效
  454. if self.lastSound then
  455. stopVoice(self.lastSound)
  456. self.lastSound = nil
  457. end
  458. -- 记录当前的音效
  459. self.lastSound = playVoice(musicFilePath)
  460. end
  461. -- //////////////////////// //////////////////////// --
  462. function MJRoomMessageView:onChatMessageResponse(event)
  463. if not event or not event.response then
  464. return
  465. end
  466. -- 用户ID
  467. local nUserId = event.response.nUserId
  468. local nSeatShowId = app.room:getViewIdByUserId(nUserId);
  469. if not nSeatShowId then
  470. print("MJRoomMessageView:onChatMessageResponse() nSeatShowId = ", nSeatShowId);
  471. return
  472. end
  473. -- //类型 1: 表情 2: 语音 3:聊天
  474. if event.response.type == 1 then
  475. -- 表情
  476. local data = json.decode(event.response.content)
  477. local Id = data.Id or 1
  478. local sexId = data.sexId
  479. self:showFace(nSeatShowId, Id,sexId);
  480. elseif event.response.type == 2 then
  481. if nSeatShowId == self.myViewId then
  482. print("MJRoomMessageView:onChatMessageResponse() 是我自己则不下载播放录音!");
  483. return
  484. end
  485. -- 语音
  486. local jsonData = json.decode(event.response.content)
  487. local recordUrl = tostring(jsonData.recordUrl)
  488. local recordTime = tonumber(jsonData.recordTime)
  489. -- 下载玩家的语音文件并播放
  490. -- 下载完成后返回该文件在本地存储的路径
  491. app.plugin:downloadRecord(nUserId, recordUrl, function(recordTag, filePath)
  492. local userId = tonumber(recordTag)
  493. local seatShowId = app.room:getViewIdByUserId(userId)
  494. if not seatShowId then
  495. print("MJRoomMessageView:onChatMessageResponse() seatShowId = ", seatShowId);
  496. return
  497. end
  498. self.playerVoice[seatShowId].filePath = filePath
  499. end);
  500. -- 记录该玩家的语音文件,重播要用
  501. self.playerVoice[nSeatShowId] = {}
  502. self.playerVoice[nSeatShowId].recordUrl = recordUrl;
  503. self.playerVoice[nSeatShowId].recordTime = recordTime;
  504. -- 该玩家头像上播放说话的效果
  505. self:showSpeakClip(nSeatShowId)
  506. elseif event.response.type == 3 then
  507. -- 聊天
  508. local data = json.decode(event.response.content)
  509. local Id = data.Id
  510. local sexId = data.sexId
  511. self:showChat(nSeatShowId, Id,sexId);
  512. elseif event.response.type == 4 then
  513. -- 道具
  514. local data = json.decode(event.response.content)
  515. local uidStarId = data.uidStarId
  516. local uidEndId = data.uidEndId
  517. local propId = data.propId
  518. local isQunFa = data.isQunFa
  519. self:showProp(uidStarId, uidEndId,propId,isQunFa)
  520. else
  521. -- 未知的
  522. end
  523. end
  524. --发送道具
  525. function MJRoomMessageView:showProp(uidStarId, uidEndId,propId,isQunFa)
  526. response = {}
  527. response.uidStarId = uidStarId
  528. response.uidEndId = uidEndId
  529. response.propId = propId
  530. response.isQunFa = isQunFa
  531. app.room:dispatchEvent({name = "showProp",response = response});
  532. end
  533. return MJRoomMessageView;