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.

400 lines
13 KiB

  1. -- 供房间使用的GPS组件
  2. local RoomGpsComponentView = class("RoomGpsComponentView",function ()
  3. return cc.Layer:create()
  4. end)
  5. function RoomGpsComponentView:ctor(maxPlayerNum,gpsButton,exitRoomCallback,dismissCallback)
  6. --RoomGpsComponentView.super.ctor(self)
  7. self.maxPlayerNum = maxPlayerNum or 4;
  8. self.userInfoList = {}
  9. self.safeDistance = 500; -- 安全距离,单位米
  10. self.gpsButton = gpsButton;
  11. --加载纹理
  12. -- loadSpriteFrameFile("res/ui/zy_fangjian/dingwei/dingwei.plist");
  13. -- app.plugin:updateLocation()
  14. self.exitRoomCallback = exitRoomCallback
  15. self.dismissCallback = dismissCallback
  16. local function onUnbind(node , eventType)
  17. logD("RoomGpsComponentView::ctor() eventType = " .. eventType)
  18. end
  19. self:addNodeEventListener(onUnbind);
  20. self:onEnter()
  21. end
  22. function RoomGpsComponentView:onEnter()
  23. --RoomGpsComponentView.super.onEnter(self)
  24. self:initBindEvent()
  25. --初始化后检测一次 如果是最新数据则直接检测 不是最新的等待最新数据
  26. local isNew = app.room:checkGpsIsNew()
  27. if isNew then
  28. app.room:updateGpsUserInfo(app.room:getMyUserId(),true)
  29. end
  30. end
  31. function RoomGpsComponentView:initBindEvent()
  32. self:bindEvent(app, "onGpsInoChanged", handler(self, self.onGpsInfoChanged))
  33. self:bindEvent(app.room, GAME_EVENT.GPS_UPDATE_USER_INFO, handler(self, self.onGpsUpdateUserInfo))
  34. end
  35. --本地GPS发生改变要通知服务器
  36. function RoomGpsComponentView:onGpsInfoChanged()
  37. app.room:checkGpsIsNew()
  38. -- local myUserId = app.room:getMyUserId() or app.user.loginInfo.uid
  39. -- local user = self.userInfoList[myUserId]
  40. -- if user then
  41. -- local isNewest = app.user:isGpsInfoNewest(user.userInfo)
  42. -- --不是最新的数据则发送给服务器同步
  43. -- if not isNewest then
  44. -- app.room:requestGpsChange()
  45. -- end
  46. -- end
  47. end
  48. function RoomGpsComponentView:onGpsUpdateUserInfo(event)
  49. local userId = event.userId
  50. local isOpenView = event.isOpenView
  51. local isGameStart = event.isGameStart
  52. local userInfoList = event.userInfoList
  53. if userInfoList then
  54. self:_updateUserInfos(userInfoList)
  55. end
  56. local isDanger = self:checkGpsDistance(userId,isGameStart)
  57. if isDanger and isOpenView then
  58. self:_showGpsView(self.maxPlayerNum, isGameStart, self.exitRoomCallback, self.dismissCallback)
  59. end
  60. end
  61. -- 更新房间内所有玩家的信息
  62. --[[
  63. maxPlayerNum --房间可容纳的最大人数
  64. userInfoList = --房间内所有玩家的信息
  65. {
  66. [nUserId] = {nSeatId = 0, userInfo = ""},
  67. [nUserId] = {nSeatId = 0, userInfo = ""},
  68. [nUserId] = {nSeatId = 0, userInfo = ""},
  69. }
  70. --]]
  71. function RoomGpsComponentView:updateUserInfos(userInfoList)
  72. self:_updateUserInfos(userInfoList)
  73. end
  74. -- 检测房间内所有玩家之间的距离
  75. -- nUserId : 如果有值,则检测该玩家和其他玩家之间的距离
  76. -- 如果没值,则检测房间内所有玩家两两之间的距离
  77. function RoomGpsComponentView:checkGpsDistance(nUserId,isGameStart)
  78. return self:_checkGpsDistance(nUserId,isGameStart)
  79. end
  80. -- 打开GPS界面
  81. -- isGameStart : 游戏是否已开始,决定了界面是显示退出房间还是解散房间
  82. -- exitRoomCallback : 玩家选择退出房间的回调
  83. -- dismissCallback : 玩家选择解散房间的回调
  84. function RoomGpsComponentView:showGpsView(isGameStart)
  85. self:_showGpsView(self.maxPlayerNum, isGameStart, self.exitRoomCallback, self.dismissCallback)
  86. end
  87. --关闭gps界面
  88. function RoomGpsComponentView:hideGpsView()
  89. if self.gpsView and not tolua.isnull(self.gpsView) then
  90. self.gpsView:removeFromParent()
  91. self.gpsView=nil
  92. end
  93. end
  94. --[[
  95. ----------------------------------------- 以下接口不对外使用 -----------------------------------------
  96. ----------------------------------------- 以下接口不对外使用 -----------------------------------------
  97. ----------------------------------------- 以下接口不对外使用 -----------------------------------------
  98. --]]
  99. -- 更新房间内所有玩家的信息
  100. function RoomGpsComponentView:_updateUserInfos(userInfoList)
  101. self.userInfoList = {}
  102. for nUserId, tt in pairs(userInfoList) do
  103. local userInfo = json.decode(tt.userInfo)
  104. self.userInfoList[nUserId] = {nSeatId = tt.nSeatId, userInfo = userInfo}
  105. end
  106. self:_updateGpsView();
  107. end
  108. -- 检测房间内玩家之间的距离
  109. function RoomGpsComponentView:_checkGpsDistance(curUserId,isGameStart)
  110. logD("RoomGpsComponentView:_checkUserDistance()", tostring(curUserId))
  111. local isDanger = false;
  112. if curUserId then
  113. logD("RoomGpsComponentView:_checkUserDistance() 和其他玩家进行比较",tostring(curUserId))
  114. local nickname1 = string.format("[%s]", self:_getUserName(curUserId))
  115. local gpsStatus, strResult = self:_checkGpsValid(curUserId)
  116. -- 提示这个人的GPS状态
  117. local str = string.format("[%s] %s", nickname1, errText1)
  118. logD("RoomGpsComponentView:_checkUserDistance() ", str)
  119. local colorStatus = GpsDefaultColor[gpsStatus or GpsStatus.unkown]
  120. local tt =
  121. {
  122. {color = GpsDefaultColor, text = nickname1},
  123. {color = colorStatus, text = strResult},
  124. }
  125. if not isGameStart then
  126. showDropTip(tt);
  127. end
  128. -- 如果没开,后面就不用和其他玩家比较了
  129. if gpsStatus ~= GpsStatus.enable then
  130. isDanger = true
  131. -- return
  132. end
  133. -- 将这个人和其他人进行比较
  134. for nUserId, v in pairs(self.userInfoList) do
  135. if curUserId ~= nUserId then
  136. local gpsStatus, errText2 = self:_checkGpsValid(nUserId)
  137. if gpsStatus == GpsStatus.enable then
  138. local ret, distance = self:_checkDistance(curUserId, nUserId)
  139. if ret and tonumber(distance) <= self.safeDistance then
  140. local nickname2 = self:_getUserName(nUserId)
  141. local nameString = string.format("[%s]和[%s]之间的距离", nickname1, nickname2)
  142. local distanceString = getDistanceDesc(tonumber(distance) or 0)
  143. local tt =
  144. {
  145. {color = GpsDefaultColor, text = nameString},
  146. {color = GpsDistanceColor.danger, text = distanceString},
  147. }
  148. if not isGameStart then
  149. showDropTip(tt)
  150. end
  151. isDanger = true;
  152. end
  153. else
  154. isDanger = true;
  155. end
  156. end
  157. end
  158. else
  159. local ttUserIdCompared = {} -- 已经比较过的玩家ID
  160. logD("RoomGpsComponentView:_checkUserDistance() 玩家之间两两进行比较")
  161. for curUserId, _ in pairs(self.userInfoList) do
  162. ttUserIdCompared[curUserId] = true
  163. while true do
  164. local nickname1 = self:_getUserName(curUserId)
  165. local gpsStatus, errText1 = self:_checkGpsValid(curUserId)
  166. if gpsStatus ~= GpsStatus.enable then
  167. -- 如果这个人的GPS数据不是有效的,则弹出提示
  168. local nameString = string.format("[%s]", nickname1)
  169. local statusString = tostring(errText1)
  170. local tt =
  171. {
  172. {color = GpsDefaultColor, text = nameString},
  173. {color = GpsStatusColor.close, text = statusString},
  174. }
  175. if not isGameStart then
  176. showDropTip(tt);
  177. end
  178. isDanger = true
  179. break;
  180. end
  181. -- 和其他人进行比较
  182. for nUserId, _ in pairs(self.userInfoList) do
  183. if not ttUserIdCompared[nUserId] then -- 不和已经已经比较过的玩家比较
  184. local nickname2 = self:_getUserName(nUserId)
  185. local gpsStatus, errText2 = self:_checkGpsValid(nUserId)
  186. if gpsStatus == GpsStatus.enable then
  187. local ret, distance = self:_checkDistance(curUserId, nUserId)
  188. if ret and tonumber(distance) <= self.safeDistance then
  189. local nickname2 = self:_getUserName(nUserId)
  190. local nameString = string.format("[%s]和[%s]之间的距离", nickname1, nickname2)
  191. local distanceString = getDistanceDesc(tonumber(distance) or 0)
  192. local tt =
  193. {
  194. {color = GpsDefaultColor, text = nameString},
  195. {color = GpsDistanceColor.danger, text = distanceString},
  196. }
  197. if not isGameStart then
  198. showDropTip(tt)
  199. end
  200. isDanger = true
  201. end
  202. else
  203. isDanger = true
  204. end
  205. end
  206. end
  207. break
  208. end
  209. end
  210. end
  211. logD("RoomGpsComponentView:_checkUserDistance()", isDanger)
  212. self:_updateGpsButtonState(isDanger);
  213. self:_updateGpsView();
  214. return isDanger
  215. end
  216. -- 计算两个玩家之间的距离
  217. function RoomGpsComponentView:_checkDistance(nUserId1, nUserId2)
  218. local ret1 = self:_checkGpsValid(nUserId1);
  219. local ret2 = self:_checkGpsValid(nUserId2);
  220. if ret1 and ret2 and ret1 == GpsStatus.enable and ret2 == GpsStatus.enable then
  221. local nickname1 = self:_getUserName(nUserId1)
  222. local nickname2 = self:_getUserName(nUserId2)
  223. local x1, y1 = self:_getUserPositon(nUserId1)
  224. local x2, y2 = self:_getUserPositon(nUserId2)
  225. local distance = getDistance(x1, y1, x2, y2)
  226. logD("RoomGpsComponentView:"..nUserId1.." "..nUserId2.." distance:"..distance)
  227. return true, distance
  228. end
  229. return false, 0
  230. end
  231. -- 判断玩家的GPS数据是否有效
  232. function RoomGpsComponentView:_checkGpsValid(nUserId)
  233. if not nUserId then
  234. logE("RoomGpsComponentView:_checkGpsValid()", "玩家id为空")
  235. return GpsStatus.unkown, "未找到用户信息"
  236. end
  237. if not self.userInfoList[nUserId] then
  238. logE("RoomGpsComponentView:_checkGpsValid()", "玩家信息不存在,玩家id:", nUserId)
  239. return GpsStatus.unkown, "未找到用户信息"
  240. end
  241. local userInfo = self.userInfoList[nUserId].userInfo
  242. logD("RoomGpsComponentView:_checkGpsValid()", tostring(nUserId), table.tostring(userInfo))
  243. if not userInfo then
  244. logD("RoomGpsComponentView:_checkGpsValid() 未找到用户信息")
  245. return GpsStatus.unkown, "未找到用户信息"
  246. end
  247. local gpsInfo = userInfo.gpsInfo
  248. if not gpsInfo then
  249. logD("RoomGpsComponentView:_checkGpsValid() 未找到定位信息")
  250. return GpsStatus.unkown, "未找到定位信息"
  251. end
  252. if gpsInfo.gpsStatus ~= GpsStatus.enable then
  253. -- 不可用状态下,坐标强制置为0
  254. gpsInfo.x = 0;
  255. gpsInfo.y = 0;
  256. return gpsInfo.gpsStatus, GpsStatusString[gpsInfo.gpsStatus or GpsStatus.close]
  257. end
  258. if not gpsInfo.x or not gpsInfo.y or tonumber(gpsInfo.x) <= 0 or tonumber(gpsInfo.y) <= 0 then
  259. logD("RoomGpsComponentView:_checkGpsValid() 定位数据错误")
  260. return GpsStatus.unkown,"定位数据错误"
  261. end
  262. return GpsStatus.enable, GpsStatusString[GpsStatus.enable]
  263. end
  264. -- 获取玩家的位置
  265. function RoomGpsComponentView:_getUserPositon(nUserId)
  266. if self.userInfoList and self.userInfoList[nUserId] and self.userInfoList[nUserId].userInfo then
  267. local gpsInfo = self.userInfoList[nUserId].userInfo.gpsInfo
  268. if gpsInfo then
  269. return gpsInfo.x or 0, gpsInfo.y or 0
  270. end
  271. end
  272. return 0, 0
  273. end
  274. -- 获取玩家的名字
  275. function RoomGpsComponentView:_getUserName(nUserId)
  276. if self.userInfoList and self.userInfoList[nUserId] and self.userInfoList[nUserId].userInfo then
  277. return self.userInfoList[nUserId].userInfo.nickname or ""
  278. end
  279. return ""
  280. end
  281. -- 打开GPS界面
  282. function RoomGpsComponentView:_showGpsView(maxPlayerNum, isGameStart, exitRoomCallback, dismissCallback)
  283. --self:hideGpsView()
  284. if self.gpsView then
  285. return
  286. end
  287. local function gpsViewCloseCallback()
  288. self.gpsView:removeFromParent()
  289. self.gpsView = nil
  290. end
  291. if self.gpsView then
  292. self.gpsView:removeFromParent()
  293. self.gpsView=nil
  294. end
  295. self.gpsView = import("luaScript.Views.Room.RoomGpsView"):new(maxPlayerNum, self.safeDistance, self.userInfoList, isGameStart, exitRoomCallback, dismissCallback, gpsViewCloseCallback)
  296. self.gpsView:setAnchorPoint(cc.p(0.5, 0.5))
  297. app:showWaitDialog(self.gpsView)
  298. end
  299. function RoomGpsComponentView:_updateGpsView()
  300. if self.gpsView then
  301. self.gpsView:updateUserInfo(self.userInfoList)
  302. end
  303. end
  304. function RoomGpsComponentView:_updateGpsButtonState(isDanger)
  305. if self.gpsButton then
  306. if isDanger then
  307. self.gpsButton:loadTextureNormal("res/ui/zy_fangjian/dingwei/dingwei_new_red.png");
  308. --加载plist可能需要时间,这里延迟一秒启动扫光动画吧
  309. --[[self.gpsButton:runAction(cc.Sequence:create(cc.DelayTime:create(1.0),cc.CallFunc:create(function ()
  310. --self:_playAni();
  311. end)));--]]
  312. else
  313. self.gpsButton:stopAllActions();
  314. self.gpsButton:removeAllChildren();
  315. self.gpsButton:loadTextureNormal("res/ui/zy_fangjian/dingwei/dingwei_new_green.png");
  316. end
  317. end
  318. end
  319. function RoomGpsComponentView:_playAni()
  320. -- 创建图片
  321. local nodeImage = cc.ImageView:createNode()
  322. nodeImage:loadTextureFromPlist("dingweiAni/dingweiAni_1.png");
  323. if self.gpsButton then
  324. self.gpsButton:addChild(nodeImage)
  325. end
  326. local size = self.gpsButton:getContentSize();
  327. nodeImage:setPosition(cc.p(size.width/2,size.height/2));
  328. --判断纹理是否存在
  329. local cache = cc.SpriteFrameCache:getInstance()
  330. local spriteFrame = cache:getSpriteFrameByName("dingweiAni/dingweiAni_1.png");
  331. if tolua.isnull(spriteFrame) then
  332. print("spriteFrame is not in cache")
  333. nodeImage:removeFromParent()
  334. return
  335. end
  336. nodeImage:runAction(cc.Sequence:create(cc.CallFunc:create(function ()
  337. local indexFace = 0;
  338. local max = 8
  339. --每隔多少秒切换一张图片
  340. local everyFrame = 0.1;
  341. local seq = cc.Sequence:create(cc.DelayTime:create(everyFrame),cc.CallFunc:create(function ()
  342. indexFace = indexFace + 1
  343. if 0 < indexFace and indexFace <= max then
  344. local name = string.format("dingweiAni/dingweiAni_%d.png",indexFace)
  345. if not tolua.isnull(nodeImage) then
  346. nodeImage:loadTexture(name, cc.TextureResType.plistType)
  347. end
  348. else
  349. indexFace = 0
  350. end
  351. end))
  352. local act = cc.RepeatForever:create(seq);
  353. nodeImage:runAction(act)
  354. end)))
  355. end
  356. return RoomGpsComponentView;