-- 供房间使用的GPS组件 local RoomGpsComponentView = class("RoomGpsComponentView",function () return cc.Layer:create() end) function RoomGpsComponentView:ctor(maxPlayerNum,gpsButton,exitRoomCallback,dismissCallback) --RoomGpsComponentView.super.ctor(self) self.maxPlayerNum = maxPlayerNum or 4; self.userInfoList = {} self.safeDistance = 500; -- 安全距离,单位米 self.gpsButton = gpsButton; --加载纹理 -- loadSpriteFrameFile("res/ui/zy_fangjian/dingwei/dingwei.plist"); -- app.plugin:updateLocation() self.exitRoomCallback = exitRoomCallback self.dismissCallback = dismissCallback local function onUnbind(node , eventType) logD("RoomGpsComponentView::ctor() eventType = " .. eventType) end self:addNodeEventListener(onUnbind); self:onEnter() end function RoomGpsComponentView:onEnter() --RoomGpsComponentView.super.onEnter(self) self:initBindEvent() --初始化后检测一次 如果是最新数据则直接检测 不是最新的等待最新数据 local isNew = app.room:checkGpsIsNew() if isNew then app.room:updateGpsUserInfo(app.room:getMyUserId(),true) end end function RoomGpsComponentView:initBindEvent() self:bindEvent(app, "onGpsInoChanged", handler(self, self.onGpsInfoChanged)) self:bindEvent(app.room, GAME_EVENT.GPS_UPDATE_USER_INFO, handler(self, self.onGpsUpdateUserInfo)) end --本地GPS发生改变要通知服务器 function RoomGpsComponentView:onGpsInfoChanged() app.room:checkGpsIsNew() -- local myUserId = app.room:getMyUserId() or app.user.loginInfo.uid -- local user = self.userInfoList[myUserId] -- if user then -- local isNewest = app.user:isGpsInfoNewest(user.userInfo) -- --不是最新的数据则发送给服务器同步 -- if not isNewest then -- app.room:requestGpsChange() -- end -- end end function RoomGpsComponentView:onGpsUpdateUserInfo(event) local userId = event.userId local isOpenView = event.isOpenView local isGameStart = event.isGameStart local userInfoList = event.userInfoList if userInfoList then self:_updateUserInfos(userInfoList) end local isDanger = self:checkGpsDistance(userId,isGameStart) if isDanger and isOpenView then self:_showGpsView(self.maxPlayerNum, isGameStart, self.exitRoomCallback, self.dismissCallback) end end -- 更新房间内所有玩家的信息 --[[ maxPlayerNum --房间可容纳的最大人数 userInfoList = --房间内所有玩家的信息 { [nUserId] = {nSeatId = 0, userInfo = ""}, [nUserId] = {nSeatId = 0, userInfo = ""}, [nUserId] = {nSeatId = 0, userInfo = ""}, } --]] function RoomGpsComponentView:updateUserInfos(userInfoList) self:_updateUserInfos(userInfoList) end -- 检测房间内所有玩家之间的距离 -- nUserId : 如果有值,则检测该玩家和其他玩家之间的距离 -- 如果没值,则检测房间内所有玩家两两之间的距离 function RoomGpsComponentView:checkGpsDistance(nUserId,isGameStart) return self:_checkGpsDistance(nUserId,isGameStart) end -- 打开GPS界面 -- isGameStart : 游戏是否已开始,决定了界面是显示退出房间还是解散房间 -- exitRoomCallback : 玩家选择退出房间的回调 -- dismissCallback : 玩家选择解散房间的回调 function RoomGpsComponentView:showGpsView(isGameStart) self:_showGpsView(self.maxPlayerNum, isGameStart, self.exitRoomCallback, self.dismissCallback) end --关闭gps界面 function RoomGpsComponentView:hideGpsView() if self.gpsView and not tolua.isnull(self.gpsView) then self.gpsView:removeFromParent() self.gpsView=nil end end --[[ ----------------------------------------- 以下接口不对外使用 ----------------------------------------- ----------------------------------------- 以下接口不对外使用 ----------------------------------------- ----------------------------------------- 以下接口不对外使用 ----------------------------------------- --]] -- 更新房间内所有玩家的信息 function RoomGpsComponentView:_updateUserInfos(userInfoList) self.userInfoList = {} for nUserId, tt in pairs(userInfoList) do local userInfo = json.decode(tt.userInfo) self.userInfoList[nUserId] = {nSeatId = tt.nSeatId, userInfo = userInfo} end self:_updateGpsView(); end -- 检测房间内玩家之间的距离 function RoomGpsComponentView:_checkGpsDistance(curUserId,isGameStart) logD("RoomGpsComponentView:_checkUserDistance()", tostring(curUserId)) local isDanger = false; if curUserId then logD("RoomGpsComponentView:_checkUserDistance() 和其他玩家进行比较",tostring(curUserId)) local nickname1 = string.format("[%s]", self:_getUserName(curUserId)) local gpsStatus, strResult = self:_checkGpsValid(curUserId) -- 提示这个人的GPS状态 local str = string.format("[%s] %s", nickname1, errText1) logD("RoomGpsComponentView:_checkUserDistance() ", str) local colorStatus = GpsDefaultColor[gpsStatus or GpsStatus.unkown] local tt = { {color = GpsDefaultColor, text = nickname1}, {color = colorStatus, text = strResult}, } if not isGameStart then showDropTip(tt); end -- 如果没开,后面就不用和其他玩家比较了 if gpsStatus ~= GpsStatus.enable then isDanger = true -- return end -- 将这个人和其他人进行比较 for nUserId, v in pairs(self.userInfoList) do if curUserId ~= nUserId then local gpsStatus, errText2 = self:_checkGpsValid(nUserId) if gpsStatus == GpsStatus.enable then local ret, distance = self:_checkDistance(curUserId, nUserId) if ret and tonumber(distance) <= self.safeDistance then local nickname2 = self:_getUserName(nUserId) local nameString = string.format("[%s]和[%s]之间的距离", nickname1, nickname2) local distanceString = getDistanceDesc(tonumber(distance) or 0) local tt = { {color = GpsDefaultColor, text = nameString}, {color = GpsDistanceColor.danger, text = distanceString}, } if not isGameStart then showDropTip(tt) end isDanger = true; end else isDanger = true; end end end else local ttUserIdCompared = {} -- 已经比较过的玩家ID logD("RoomGpsComponentView:_checkUserDistance() 玩家之间两两进行比较") for curUserId, _ in pairs(self.userInfoList) do ttUserIdCompared[curUserId] = true while true do local nickname1 = self:_getUserName(curUserId) local gpsStatus, errText1 = self:_checkGpsValid(curUserId) if gpsStatus ~= GpsStatus.enable then -- 如果这个人的GPS数据不是有效的,则弹出提示 local nameString = string.format("[%s]", nickname1) local statusString = tostring(errText1) local tt = { {color = GpsDefaultColor, text = nameString}, {color = GpsStatusColor.close, text = statusString}, } if not isGameStart then showDropTip(tt); end isDanger = true break; end -- 和其他人进行比较 for nUserId, _ in pairs(self.userInfoList) do if not ttUserIdCompared[nUserId] then -- 不和已经已经比较过的玩家比较 local nickname2 = self:_getUserName(nUserId) local gpsStatus, errText2 = self:_checkGpsValid(nUserId) if gpsStatus == GpsStatus.enable then local ret, distance = self:_checkDistance(curUserId, nUserId) if ret and tonumber(distance) <= self.safeDistance then local nickname2 = self:_getUserName(nUserId) local nameString = string.format("[%s]和[%s]之间的距离", nickname1, nickname2) local distanceString = getDistanceDesc(tonumber(distance) or 0) local tt = { {color = GpsDefaultColor, text = nameString}, {color = GpsDistanceColor.danger, text = distanceString}, } if not isGameStart then showDropTip(tt) end isDanger = true end else isDanger = true end end end break end end end logD("RoomGpsComponentView:_checkUserDistance()", isDanger) self:_updateGpsButtonState(isDanger); self:_updateGpsView(); return isDanger end -- 计算两个玩家之间的距离 function RoomGpsComponentView:_checkDistance(nUserId1, nUserId2) local ret1 = self:_checkGpsValid(nUserId1); local ret2 = self:_checkGpsValid(nUserId2); if ret1 and ret2 and ret1 == GpsStatus.enable and ret2 == GpsStatus.enable then local nickname1 = self:_getUserName(nUserId1) local nickname2 = self:_getUserName(nUserId2) local x1, y1 = self:_getUserPositon(nUserId1) local x2, y2 = self:_getUserPositon(nUserId2) local distance = getDistance(x1, y1, x2, y2) logD("RoomGpsComponentView:"..nUserId1.." "..nUserId2.." distance:"..distance) return true, distance end return false, 0 end -- 判断玩家的GPS数据是否有效 function RoomGpsComponentView:_checkGpsValid(nUserId) if not nUserId then logE("RoomGpsComponentView:_checkGpsValid()", "玩家id为空") return GpsStatus.unkown, "未找到用户信息" end if not self.userInfoList[nUserId] then logE("RoomGpsComponentView:_checkGpsValid()", "玩家信息不存在,玩家id:", nUserId) return GpsStatus.unkown, "未找到用户信息" end local userInfo = self.userInfoList[nUserId].userInfo logD("RoomGpsComponentView:_checkGpsValid()", tostring(nUserId), table.tostring(userInfo)) if not userInfo then logD("RoomGpsComponentView:_checkGpsValid() 未找到用户信息") return GpsStatus.unkown, "未找到用户信息" end local gpsInfo = userInfo.gpsInfo if not gpsInfo then logD("RoomGpsComponentView:_checkGpsValid() 未找到定位信息") return GpsStatus.unkown, "未找到定位信息" end if gpsInfo.gpsStatus ~= GpsStatus.enable then -- 不可用状态下,坐标强制置为0 gpsInfo.x = 0; gpsInfo.y = 0; return gpsInfo.gpsStatus, GpsStatusString[gpsInfo.gpsStatus or GpsStatus.close] end if not gpsInfo.x or not gpsInfo.y or tonumber(gpsInfo.x) <= 0 or tonumber(gpsInfo.y) <= 0 then logD("RoomGpsComponentView:_checkGpsValid() 定位数据错误") return GpsStatus.unkown,"定位数据错误" end return GpsStatus.enable, GpsStatusString[GpsStatus.enable] end -- 获取玩家的位置 function RoomGpsComponentView:_getUserPositon(nUserId) if self.userInfoList and self.userInfoList[nUserId] and self.userInfoList[nUserId].userInfo then local gpsInfo = self.userInfoList[nUserId].userInfo.gpsInfo if gpsInfo then return gpsInfo.x or 0, gpsInfo.y or 0 end end return 0, 0 end -- 获取玩家的名字 function RoomGpsComponentView:_getUserName(nUserId) if self.userInfoList and self.userInfoList[nUserId] and self.userInfoList[nUserId].userInfo then return self.userInfoList[nUserId].userInfo.nickname or "" end return "" end -- 打开GPS界面 function RoomGpsComponentView:_showGpsView(maxPlayerNum, isGameStart, exitRoomCallback, dismissCallback) --self:hideGpsView() if self.gpsView then return end local function gpsViewCloseCallback() self.gpsView:removeFromParent() self.gpsView = nil end if self.gpsView then self.gpsView:removeFromParent() self.gpsView=nil end self.gpsView = import("luaScript.Views.Room.RoomGpsView"):new(maxPlayerNum, self.safeDistance, self.userInfoList, isGameStart, exitRoomCallback, dismissCallback, gpsViewCloseCallback) self.gpsView:setAnchorPoint(cc.p(0.5, 0.5)) app:showWaitDialog(self.gpsView) end function RoomGpsComponentView:_updateGpsView() if self.gpsView then self.gpsView:updateUserInfo(self.userInfoList) end end function RoomGpsComponentView:_updateGpsButtonState(isDanger) if self.gpsButton then if isDanger then self.gpsButton:loadTextureNormal("res/ui/zy_fangjian/dingwei/dingwei_new_red.png"); --加载plist可能需要时间,这里延迟一秒启动扫光动画吧 --[[self.gpsButton:runAction(cc.Sequence:create(cc.DelayTime:create(1.0),cc.CallFunc:create(function () --self:_playAni(); end)));--]] else self.gpsButton:stopAllActions(); self.gpsButton:removeAllChildren(); self.gpsButton:loadTextureNormal("res/ui/zy_fangjian/dingwei/dingwei_new_green.png"); end end end function RoomGpsComponentView:_playAni() -- 创建图片 local nodeImage = cc.ImageView:createNode() nodeImage:loadTextureFromPlist("dingweiAni/dingweiAni_1.png"); if self.gpsButton then self.gpsButton:addChild(nodeImage) end local size = self.gpsButton:getContentSize(); nodeImage:setPosition(cc.p(size.width/2,size.height/2)); --判断纹理是否存在 local cache = cc.SpriteFrameCache:getInstance() local spriteFrame = cache:getSpriteFrameByName("dingweiAni/dingweiAni_1.png"); if tolua.isnull(spriteFrame) then print("spriteFrame is not in cache") nodeImage:removeFromParent() return end nodeImage:runAction(cc.Sequence:create(cc.CallFunc:create(function () local indexFace = 0; local max = 8 --每隔多少秒切换一张图片 local everyFrame = 0.1; local seq = cc.Sequence:create(cc.DelayTime:create(everyFrame),cc.CallFunc:create(function () indexFace = indexFace + 1 if 0 < indexFace and indexFace <= max then local name = string.format("dingweiAni/dingweiAni_%d.png",indexFace) if not tolua.isnull(nodeImage) then nodeImage:loadTexture(name, cc.TextureResType.plistType) end else indexFace = 0 end end)) local act = cc.RepeatForever:create(seq); nodeImage:runAction(act) end))) end return RoomGpsComponentView;