【泡泡堂】格子管理等

<1>不少人都玩過炸彈人或者泡泡堂,以前作了這個玩法,記錄一下關鍵實現緩存

<2>直接上Lua代碼服務器

1.維護每一個格子上的物體 好比:BUFF類,寶箱,草箱,木箱,鐵箱,炸彈,小怪...ui

用一個結構維護一個格子31*31=961,進入場景建立,離開釋放掉this

每一個結構裏面聲明一張map緩存格子裏面全部的物體 <物體類型,map<物體uid,true>>spa

2.計算炸彈爆炸所影響的格子(長寬不等的十字形)server

炸彈有一個威力等級Force,計算規則爲 Force*2+1 = 同一軸上所影響的格子對象

可是碰到鐵箱子是沒法穿透的,全部這個爆炸的十字形多是長寬不等的blog

BombermanMgr = { }

local _isInit = false
local rowNum = 31
local colNum = 31
local cellSize = 2
-- -22 30 對應 -21.945  29.925 要麼場景作偏移 要麼起始X Y作偏移 -0.055  0.075
-- 場景作偏移  
local startX = -31  
local startY = -31
local function create_self_param(self)
    if _isInit == ture then
        return
    end
    -- 導入依賴的文件
    -- 初始化
    self:__init_self_param()
end

local function create(self)
    create_self_param(self)
end

-- 初始化成員
function BombermanMgr:__init_self_param()
   self.boxPool = nil --緩存961格子信息 BoxData
   self.dropPool = { } --緩存掉落物 entity
   self.memberPool = { } --玩家信息 PPTMemberData
   self.rankPool = { }--玩家信息 PPTMemberRankData
   self.rankMap = { }--玩家排名 PPTMemberRankData
   self.skillPool = nil --玩家技能信息
   self.mainRoleId = 0
   --排行數據
   self.todayReqTime = -1 --上次拉取時間
   self.yestodayReqTime = -1 --上次拉取時間
   self.todayLst = { } --今天數據
   self.yestodayLst = { }--昨天數據
   self.todayMine = nil --本身今天
   self.yestodayMine = nil --本身昨天
   self.myRespawnRoleId = nil --出生點模型
   self.followId = -1 --跟隨id
   self.lastAlertTime = -1--上次彈出提示時間
   self.bombEffectTimeMap = { }--格子爆炸特效上次釋放時間
   self.audioTimeMap = { }--音效上次播放時間

   --self.combineLst = ListLong() --須要合併的對象
   self.combineRoot = nil --合併根節點
   self.combineNum = 0

   --無需清理
   self.infoHandler = nil 
   self.rankRewardLst = nil 
end

function BombermanMgr:getMainPlayerId()
   return self.mainRoleId
end 

function BombermanMgr:getMaxIndex()
  return rowNum*colNum
end 

--技能信息
--新實體協議下發 初始化技能 根據實體中的寵物id獲取充能次數...
function BombermanMgr:initSkill(petId)
      self.skillPool = { }
      local pptCfg = BombermanUtils:getPetConfigById(petId)
      if not pptCfg then 
         Logger:logError("沒有讀取到PptPetConfig id ",petId)
         return 
      end 
      local boomData = PPTSkillData(PPTSkillType.boom,PPTBombForceIcon[1],BombermanConst.bombCooldown,pptCfg.bomCharge)
      self.skillPool[PPTSkillType.boom] = boomData

      local speedData = PPTSkillData(PPTSkillType.speed,BombermanConst.speedIcon,BombermanConst.speedCooldown,pptCfg.speedRune)
      self.skillPool[PPTSkillType.speed] = speedData

      local superData = PPTSkillData(PPTSkillType.super,BombermanConst.superIcon,BombermanConst.superCooldown,pptCfg.snvincibleRune)
      self.skillPool[PPTSkillType.super] = superData

      local hpData = PPTSkillData(PPTSkillType.hp,BombermanConst.hpIcon,BombermanConst.hpCooldown,pptCfg.life)
      self.skillPool[PPTSkillType.hp] = hpData
end 

function BombermanMgr:getSkillLst()
   return self.skillPool
end 
--計數數據更新
function BombermanMgr:updateSkill(skillType,count,force)
   local dt = self.skillPool[skillType]
   if dt then 
      if force then 
         dt:setForceLevel(force)
      end 
      if count then 
         dt:onCountChange(count)
      end 
   end 
end 

function BombermanMgr:addSkillCount(skillType)
   local dt = self.skillPool[skillType]
   if dt then 
      dt:addChargeNum(1)
   end 
end 

--配置靜態盒子
--2次for循環 中間少了的固定格子寫死
function BombermanMgr:initBox()
	self.boxPool = { }
    --把固定格子建立出來
    local ignore = { }
    ignore[419] = true 
    ignore[479] = true 
    ignore[481] = true 
    ignore[483] = true 
    ignore[543] = true 
	for i = 1,15 do
	    local num = 31+2*i
		for k = 1,15 do
		    local num2 = num+31*(k-1)*2
			if ignore[num2] == nil then 
		   	    local data = BoxData(BoxType.metalBox,MathUtils:getUniqueID())
		   	    self.boxPool[num2] = data	
			end 
		end
	end 
	--建立剩餘的格子 默認爲空格子
	for i = 1,rowNum*colNum do 
		if self.boxPool[i] == nil then 
	       local data = BoxData(BoxType.emptyBox,MathUtils:getUniqueID())
	       self.boxPool[i] = data	
	    end 
    end 
end 

--隱射一個實體類型
local entityMap = { }
entityMap[BoxType.bombBox] = LBoxHinderBombEntity

local function getClass(type)
    local class = entityMap[type]
    if class == nil then
        class = LBoxHinderEntity
    end
    return class
end

--建立靜態實體
function BombermanMgr:createBox(msg)
  	local index = msg.gridId
  	local id = msg.livingId 
  	local btype = msg.type
    local masterId = msg.playerId
  	local modelId = BoxType2Model[btype]
    if btype == BoxType.bombBox then 
        modelId = masterId<=0 and BombermanConst.bossBombModelId or modelId
        --音效:炸彈建立 
        if masterId*10 == self:getMainPlayerId() then 
           self:playAudio(BombermanConst.bombCastAudioId, nil)
        end 
    end 
  	local pos = self:getBoxCenterPos(index)
    --data
    local roleData = LRoleData(id, RoleType.BoxHinder, true)
    roleData:changeAttr(RoleAttr.SkinId,modelId)
    roleData:changeAttr(RoleAttr.Fight,index)
    roleData:changeAttr(RoleAttr.Exp,btype)
    roleData:changeAttr(RoleAttr.MasterId,masterId)
    --roleData:changeAttr(RoleAttr.MountId,msg.blood)
    --roleData:changeAttr(RoleAttr.MagicWeaponId,msg.maxBlood)
    roleData:changeAttr(RoleAttr.isActive,true)
    roleData:changeAttr(RoleAttr.InitPosition, pos)
    roleData:setFull()
    roleData:attach()
    --建立
    if StaticEntityMgr:getRoleData(id) ~= nil then 
        return 
    end 
    local class = getClass(btype)
    local staticEntity = class(id, RoleType.BoxHinder, roleData , nil)
    if staticEntity then 
        if self.boxPool[index] then 
           self.boxPool[index]:addType(btype,id)
        end 
        StaticEntityMgr:addRoleData(roleData)
        StaticEntityMgr:addRole(staticEntity)
        staticEntity:create()      
    end
end 
--移除觸發器實體
function BombermanMgr:removeBox(msg)    
    local id = msg.livingId 
    local index = msg.gridId
    local btype = msg.type
    if self.boxPool[index] then 
       self.boxPool[index]:removeType(btype,id)
    end 
    StaticEntityMgr:removeRole(id)
    StaticEntityMgr:removeRoleData(id)
    --移除的盒子須要有特效 則播放特效
    self:playEffect(btype,index)
end 

--有的盒子銷燬須要播放特效
function BombermanMgr:playEffect(btype,idx)
    if BoxType2ExplodeEffect[btype] ~= nil then 
        local pos = self:getBoxCenterPos(idx)
        EffectMgr:createEffect(BoxType2ExplodeEffect[btype], pos, nil)
    end
    --寶箱移除 播放音效 
    if btype == BoxType.treasureBox then 
       self:playAudio(BombermanConst.openTreasureAudioId, nil)
    end 
end 

--協議更新盒子
function BombermanMgr:updateBox(msg)
	if self.boxPool == nil then 
		 self:initBox()
	end 
	local index = msg.gridId
	local btype = msg.type
	local uid = msg.livingId
	local isAdd = msg.blood > 0 --再也不使用狀態字段 blood就能夠標記這個狀態了
	if self.boxPool[index] then
		if isAdd then 
			self:createBox(msg)
			self.boxPool[index]:addType(btype,uid)
		else
			self:removeBox(msg)
			self.boxPool[index]:removeType(btype,uid)
		end 
	end
end 

--怪物移動
--在格子上添加移除
function BombermanMgr:simpleAddType(index,btype,uid)
    local boxData = self:getBoxData(index)
    if boxData then 
       boxData:addType(btype,uid)
    end 
end 
function BombermanMgr:simpleRemoveType(index,btype,uid)
    local boxData = self:getBoxData(index)
    if boxData then 
       boxData:removeType(btype,uid)
    end 
end 

--是否能夠移動到目標位置
function BombermanMgr:canMoveTo(nowIndex,targetPos)
	local index = self:getCellIndex(targetPos)
	--若是玩家在當前格子 能夠移動
	if index == nowIndex then 
		return true 
	end 
	--沒有找到格子 沒法移動
	if self.boxPool[index] == nil then 
		return true 
	end 
    --最後返回目標格子沒有阻擋物
	return not self.boxPool[index]:getIsHinder()
end 

function BombermanMgr:canMoveToByPos(nowPos,targetPos)
	  local index = self:getCellIndex(nowPos)
    return self:canMoveTo(index,targetPos)
end 

--炸彈爆炸全部格子
--服務器推 爆炸點 炸彈等級 客戶端計算出在哪些格子實例化炸彈
function BombermanMgr:getExplodeIndexs(index,level)
   local lst = { }
   local dirMap = { }--4個方向的數量
   dirMap.top = 0
   dirMap.bottom = 0
   dirMap.left = 0
   dirMap.right = 0
   lst[1] = index
   local row = self:getIndexRow(index)
   --local col = self:getIndexCol(index)
   local boxData = self:getBoxData(index)
   if boxData == nil then 
   	  return lst
   end 
   local unlockTop = true
   local unlockBottom = true
   local unlockLeft = true
   local unlockRight = true
   for i = 1,level do 
   	   local top = index-rowNum*i 
   	   local bottom = index+rowNum*i 
   	   local left = index-i
   	   local right = index+i
   	   --驗證是否合理 
   	   --top不能<=0  bottom不能>31  left right 驗證同一行既可
   	   --公共條件 有的(鐵格子)無需放炸彈 被鐵格子擋住了 也沒法繼續延伸釋放炸彈
   	   if unlockTop and top > 0 then 
   	   	  unlockTop,canAdd = self:canPlaceExplode(top,level)
          if unlockTop then 
             dirMap.top = dirMap.top + 1
          end 
   	   	  if canAdd then              
             table.insert(lst,top)
          end 
   	   end 
   	   if unlockBottom and bottom <= rowNum*colNum then 
   	   	  unlockBottom,canAdd = self:canPlaceExplode(bottom,level)
          if unlockBottom then 
             dirMap.bottom = dirMap.bottom + 1 
          end 
   	   	  if canAdd then             
             table.insert(lst,bottom)
          end 
   	   end 
   	   --left right 
   	   if unlockLeft and self:getIndexRow(left) == row then 
   	   	   unlockLeft,canAdd = self:canPlaceExplode(left,level)
           if unlockLeft then 
              dirMap.left = dirMap.left + 1
           end 
   	   	   if canAdd then               
   	   	      table.insert(lst,left)
   	   	   end 
   	   end 
   	   if unlockRight and self:getIndexRow(right) == row then 
   	   	   unlockRight,canAdd = self:canPlaceExplode(right,level)
           if unlockRight then 
              dirMap.right = dirMap.right + 1
           end 
   	   	   if canAdd then               
   	   	      table.insert(lst,right)
   	   	   end 
   	   end 
   end
   return lst,dirMap
end

--格子是否能夠放置炸彈爆炸物
--return 1是否被阻擋 2是否能夠爆炸
function BombermanMgr:canPlaceExplode(index,level)
   local boxData = self:getBoxData(index)
   if boxData == nil then 
   	  return true,true 
   end
   if boxData:hasType(BoxType.metalBox) then 
      return false,false
   elseif boxData:hasType(BoxType.grassBox) then 
      return false,true--level>=3
   elseif boxData:hasType(BoxType.woodBox) then 
      return false,true--level>=1
   end 
   return true,true 
   --return not boxData:hasType(BoxType.metalBox) and not boxData:hasType(BoxType.grassBox) and not boxData:hasType(BoxType.woodBox)
end 

--根據index獲取行列
function BombermanMgr:getIndexRow(index)
	return math.ceil(index/rowNum)
end 
function BombermanMgr:getIndexCol(index)
    local col = index%rowNum
    return col == 0 and rowNum or col 
end 

--獲取格子數據
function BombermanMgr:getBoxData(index)
	return self.boxPool[index]
end 

--根據位置獲取格子index
function BombermanMgr:getCellIndex(pos)
    local x = pos.x 
    local y = pos.z
    local rowIndex = math.ceil((x - startX)/cellSize) 
    local colIndex = math.ceil((y - startY)/cellSize) 
    return (colIndex-1)*rowNum+rowIndex
end

--獲取格子對應的座標(取格子中心)
function BombermanMgr:getBoxCenterPos(index)
   local row = self:getIndexRow(index)
   local col = self:getIndexCol(index)
   local x = startX+(col-1)*cellSize+(cellSize/2) --x是遞加
   local y = startY+(row-1)*cellSize+(cellSize/2) --y是遞加
   return Vector3(x,0,y)
end 

--獲取當前格子九宮格
function BombermanMgr:getSudokuBoxs(index)
   local lst = self:getRoundIndex(index)
   local boxLst = { }
   for k,v in pairs(lst) do 
   	   local data = self:getBoxData(k)
   	   if data then 
   	   	  table.insert(boxLst,data)
   	   end 
   end 
   return boxLst
end 

--獲取格子周圍全部格子
function BombermanMgr:getRoundIndex(index)
	    local lst = {}
		--top 沒有上 r1r2r3 --bottom沒有下 r6r7r8 --left沒有左r1r4r6  --right沒有右r3r5r8
		local isTop = index<=rowNum
		local isBottom = index > (colNum-1)*rowNum
		local isLeft = index%rowNum == 1
		local isRight = index%rowNum == 0
		local filter = {}
		local r1 = index - rowNum - 1
		local r2 = index - rowNum
		local r3 = index - rowNum + 1
		local r4 = index - 1
		local r5 = index + 1
		local r6 = index + rowNum - 1
		local r7 = index + rowNum
		local r8 = index + rowNum + 1
		if isTop then
		    filter[r1] = true
			filter[r2] = true
			filter[r3] = true
	    end
		if isBottom then
		    filter[r6] = true
			filter[r7] = true
			filter[r8] = true
	    end
		if isLeft then
		    filter[r1] = true
			filter[r4] = true
			filter[r6] = true
	    end
		if isRight then
		    filter[r3] = true
			filter[r5] = true
			filter[r8] = true
	    end	   
		local result = {r1,r2,r3,r4,r5,r6,r7,r8}
		for i =1,#result do
		    if filter[result[i]] == nil then
		        lst[result[i]] = true 
			end
		end
		lst[index] = true 
		return lst
end 

function BombermanMgr:isVaildMove(nowIndex,targetPos)
   local index = self:getCellIndex(targetPos)
   return index == nowIndex+1 or index == nowIndex-1 or index == nowIndex+rowNum*1 or index == nowIndex+rowNum-1
end 

--動態修改層級
--若是玩家當前格子有阻礙物
--設置當前阻礙物爲role層 不與玩家發生碰撞
--在玩家更換格子以後 把層級設置回來 
function BombermanMgr:changeLayer(index,layerName)
    local boxData = self:getBoxData(index)
    if boxData and boxData:getIsHinder() then 
        for k,v in pairs(BoxHinderType) do 
            local map = boxData:getTypeLst(k) 
            if map then 
                for m,n in pairs(map) do --m = uid n = true 
                    if n == true then 
                        EntityUtils:changeStaticRoleLayer(m, LayerMask.NameToLayer(layerName))
                    end 
                end 
            end 
        end 
    end 
end 

--阻礙物加載完成
function BombermanMgr:checkLayer(hinderIndex,uid)
    local playerIndex = -1
    local role = EntityMgr:getRole(self:getMainPlayerId())
    if role then 
       playerIndex = role:getCellIndex()
    end 
    if hinderIndex == playerIndex then 
       --self:changeLayer(hinderIndex,'Role')
       EntityUtils:changeStaticRoleLayer(uid, LayerMask.NameToLayer('Role'))
    end 
end 


-------------------------------如下緩存玩家信息---------------------------------
function BombermanMgr:addInfoListener(handler)
   self.infoHandler = handler--不須要清理
end 

function BombermanMgr:invokeInfoHandler()
    if self.infoHandler then 
       self.infoHandler()
    end 
end 
--PPTMemberData  (uid,name,serverName,job,transferJob)
function BombermanMgr:addMember(id,msg)
    if self.memberPool[id] == nil then
        local dt = PPTMemberData(id,msg.nick_name,msg.serverName,msg.tempId,msg.lifeCount)
        self.memberPool[id] = dt 
        self:invokeInfoHandler()
    end 
end  
function BombermanMgr:updateMemberHp(id,hp)
    local dt = self.memberPool[id]
    if dt then 
       dt:setHp(hp)
    end 
    self:invokeInfoHandler()
end  

function BombermanMgr:getMemberLst()
   return self.memberPool
end 

--rankPool
function BombermanMgr:addRank(id,msg)
    if self.rankMap[id] == nil then 
        local dt = PPTMemberRankData(id,msg.nick_name,msg.serverName)
        table.insert(self.rankPool,dt) --lst 排序
        self.rankMap[id] = dt --map 快速查找
        self:invokeInfoHandler()
    end
end

function BombermanMgr:updateRank(id,score)
    local dt = self.rankMap[id]
    if dt then 
       dt:setScore(score)
    end 
    table.sort(self.rankPool,function(m,n) return m:getScore()>n:getScore() end)
    self:invokeInfoHandler()
end 

function BombermanMgr:getRankLst()
   return self.rankPool
end 

function BombermanMgr:getScore(id)
   return self.rankMap[id] and self.rankMap[id]:getScore() or 0
end   

--如下排行榜相關 PPTRankData:__init(id,rank,nickName,score)
function BombermanMgr:addTodayLst(msg)
   self.todayLst = { }
   local lst = msg.allReports
   if lst and #lst>0 then 
      for i = 1,#lst do 
        local rsp = lst[i]
        local dt = PPTRankData(rsp.livingId,rsp.rank,rsp.nickName,rsp.toalScore)
        table.insert(self.todayLst,dt) 
      end 
   end 
   table.sort(self.todayLst,function(m,n) return m:getRank()<n:getRank() end)
   local rsp = msg.meInfos
   self.todayMine = PPTRankData(rsp.livingId,rsp.rank,rsp.nickName,rsp.toalScore)
end 
function BombermanMgr:addYesTodayLst(msg)
   self.yestodayLst = { }
   local lst = msg.allReports
   if lst and #lst>0 then 
      for i = 1,#lst do 
        local rsp = lst[i]
        local dt = PPTRankData(rsp.livingId,rsp.rank,rsp.nickName,rsp.toalScore)
        table.insert(self.yestodayLst,dt) 
      end 
   end 
   table.sort(self.yestodayLst,function(m,n) return m:getRank()<n:getRank() end)
   local rsp = msg.meInfos
   self.yestodayMine = PPTRankData(rsp.livingId,rsp.rank,rsp.nickName,rsp.toalScore) 
end 

function BombermanMgr:getTodayLst()
  return self.todayLst,self.todayMine
end 

function BombermanMgr:getYesTodayLst()
  return self.yestodayLst,self.yestodayMine
end 

function BombermanMgr:canReqToday()
   return TimerMgr:getServerTime() - self.todayReqTime > 60*1000--60S才能拉取
end 

function BombermanMgr:canReqYesToday()
   return TimerMgr:getServerTime() - self.yestodayReqTime > 60*1000--60S才能拉取
end 

function BombermanMgr:resetReqToday()
  self.todayReqTime = TimerMgr:getServerTime()
end 
function BombermanMgr:resetReqYesToday()
  self.yestodayReqTime = TimerMgr:getServerTime()
end 

function BombermanMgr:getRankRewards()    
    if self.rankRewardLst == nil then
        self.rankRewardLst = {}
        local list = RewardConfigMgr:getRewardConfigList(RewardType.PPTAllRank)
        if list then
          for i = 1, #list do
            local data = DemonAwardData(list[i])
            self.rankRewardLst[#self.rankRewardLst + 1] = data
          end
        else
          Logger:logError("can not find RewardConfig type =", RewardType.PPTAllRank)
        end
    end
    return self.rankRewardLst 
end 

--出生點模型 BombermanConst.myRespawnModeltId
function BombermanMgr:checkMyRespawnModel(idx)
   if not self.myRespawnRoleId then 
      local pos = self:getBoxCenterPos(idx)
      --data
      self.myRespawnRoleId = MathUtils:getUniqueID()
      local roleData = LRoleData(self.myRespawnRoleId, RoleType.BoxHinder, true)
      roleData:changeAttr(RoleAttr.SkinId,BombermanConst.myRespawnModeltId)
      roleData:changeAttr(RoleAttr.isActive,true)
      roleData:changeAttr(RoleAttr.InitPosition, pos)
      roleData:setFull()
      roleData:attach()
      --建立
      local staticEntity = LBoxHinderEntity(self.myRespawnRoleId, RoleType.BoxHinder, roleData , nil)
      if staticEntity then 
          StaticEntityMgr:addRoleData(roleData)
          StaticEntityMgr:addRole(staticEntity)
          staticEntity:create()      
      end
   end 
end 

--是否能夠釋放
function BombermanMgr:canCastBomb(isAlert)
    local role = EntityMgr:getRole(self:getMainPlayerId())
    if role then 
       local roleIndex = role:getCellIndex()
       local boxData = self:getBoxData(roleIndex)
       if boxData and boxData:hasType(BoxType.bombBox) then 
            if isAlert then 
                --1000ms才能彈出1次提示
                if TimerMgr:getServerTime() - self.lastAlertTime > 800 then 
                   self.lastAlertTime = TimerMgr:getServerTime()
                   UIUtils:floatAlertByKey(BombermanLang.thisBoxHasBombStr)
                end 
            end 
           return false 
       end 
    end 
    return true 
end 

function BombermanMgr:isFollowPlayer(id)
   return id == self.followId
end 

--格子是否能夠實例化爆炸特效
function BombermanMgr:canPlayCellEffect(index,time)
   if not self.bombEffectTimeMap[index] or time - self.bombEffectTimeMap[index] > 500 then 
      self.bombEffectTimeMap[index] = time 
      return true 
   end 
   return false 
end 

--接口 index1是否在index2的 14*14範圍內 用於播放音效
function BombermanMgr:indexIn14Range(mine,target)
    local mineRow =  self:getIndexRow(mine)
    local mineCol = self:getIndexCol(mine)
    local tarRow = self:getIndexRow(target)
    local tarCol = self:getIndexCol(target)
    return math.abs(tarRow-mineRow) <= 7 and math.abs(tarCol-mineCol) <= 7
end 

--封裝一層 音效播放
function BombermanMgr:playAudio(audioId, callBack)
    if audioId and audioId > 0 and self:canPlayAudioTime(audioId) then 
       AudioMgr:playAudio(audioId, callBack) 
    end
end 

function BombermanMgr:canPlayAudioTime(audioId)
     local time = TimerMgr:getServerTime()
     local mill = AudioIdMinMill[audioId] and AudioIdMinMill[audioId] or 0 
     if not self.audioTimeMap[audioId] or time - self.audioTimeMap[audioId] > mill then 
        self.audioTimeMap[audioId] = time 
        return true 
     end 
     return false  
end 

--合併
function BombermanMgr:addStaticId(id)
    --table.insert(self.combineLst,id)
    self.combineLst:Add(id)
    if self.combineLst.Count>=1 then 
       --combine
       EntityUtils:combineStatic(self.combineLst)
       self.combineLst:Clear()
    end 

end 

---[[
function BombermanMgr:addToStatic(id)
    if self.combineRoot == nil or not Helper:goIsHas(self.combineRoot) then 
       self.combineRoot = GameObject("combineRoot")
    end 
    EntityUtils:setStaticParent(id,self.combineRoot)
    self.combineNum = self.combineNum + 1
    if self.combineNum >= 15 then 
       if self.combineRoot ~= nil and Helper:goIsHas(self.combineRoot) then
           --Logger:logError("combineRoot")
           StaticBatchingUtility.Combine(self.combineRoot)
           self.combineNum = 0
       end
    end 
end 
--]]

-- 清理數據
function BombermanMgr:clearSelf()
	 self.boxPool = nil 
   self.mainRoleId = 0
	 self.dropPool = { } --緩存掉落物 BUFF 
   self.memberPool = { } --玩家信息 PPTMemberData
   self.rankPool = { }--玩家信息 PPTMemberRankData
   self.rankMap = { }--玩家排名 PPTMemberRankData
   self.todayReqTime = -1 --上次拉取時間
   self.yestodayReqTime = -1 --上次拉取時間
   self.todayLst = { } --今天數據
   self.yestodayLst = { }--昨天數據
   self.todayMine = nil --本身今天
   self.yestodayMine = nil --本身昨天
   self.myRespawnRoleId = nil --出生點模型
   self.followId = -1 --跟隨id
   self.lastAlertTime = -1--上次彈出提示時間
   self.bombEffectTimeMap = { }--格子爆炸特效上次釋放時間
   self.audioTimeMap = { }--音效上次播放時間
   --self.combineLst = ListLong()
   self.combineNum = 0
end
---------如下段落實現一些須要的定義方法-------end-------------------------

-- 自動初始化
create(BombermanMgr)

  

<3>代碼備註排序

--[[
實體建立:
5,6號協議主角仍是會建立(進入不會推)
在進入這個場景的時候,建立完畢炸彈人實體(繼承LRole),相機進行跟隨
同時關閉全部原先RootUI,搖桿從新建立一個新的(複用預設,class重寫),技能UI也作新的(所有重寫) 頭像 任務UI都重作

位置同步:
客戶端A搖桿拖動開始同步 中止移動也同步一次
客戶端A每次預測當前方向0.1秒位置,預測位置發送給服務器,服務器進行廣播
客戶端A每次移動都檢測是否碰撞到阻擋格子
客戶端B接到同步協議,進行插值移動
怪物位置同步:
服務器每次推送怪物目標格子
客戶端把每一個格子位置加入到怪物的目標位置列表
客戶端進行平滑插值 速度會根據列表中的個數進行加速度

碰撞器:
碰撞器使用Unity自帶碰撞
若是玩家卡到格子裏面 那麼格子裏面的物體碰撞層都會設置成不與玩家碰撞

觸發器:
不適用Unity觸發器 在Lua這邊維護觸發
主角每次改變格子 都會檢測觸發(檢測當前格子和九宮格,盒子生成也須要與玩家所在格子檢測)

BUFF:
buff存在於實體身上(對應關係備註在BombermanConst)
buff服務器只告訴結束時間戳 客戶端本身維護BUFF結束 沒法使用以前的buff組件
實體獲取buff起定時器 每100ms檢查buff是否結束 使用setCountDown定時器會有後臺運行的問題(後臺運行定時器暫停)
主角buff定時器每次都拋出消息給UI

技能:
技能分爲3中類型 1炸彈(能夠充能) 2符文(使用一層少一層) 3血量(死亡一次少一次)
技能數據都存在於實體身上(對應關係備註在BombermanConst)
1炸彈充能 有最大充能次數(會動態更改)
2符文
3血量

其餘:
1.進入PPT場景主動拉取全部信息(否則會出現還沒加載完場景 協議來了建立實體 實體又立刻被銷燬)
2.進入PPT場景 服務器仍是會推其餘玩家的6號協議(服務器通用處理) 客戶端PPT玩家實體的id = id*10 取實體的 更新實體都須要*10
3.玩家實體建立協議與怪物實體建立協議不一樣(怪物實體用的是Box協議 客戶端轉實體)
--]]
相關文章
相關標籤/搜索