【泡泡堂】格子管理等

<1>很多人都玩过炸弹人或者泡泡堂,之前做了这个玩法,记录一下关键实现

<2>直接上Lua代码

1.维护每个格子上的物体 比如:BUFF类,宝箱,草箱,木箱,铁箱,炸弹,小怪...

用一个结构维护一个格子31*31=961,进入场景创建,离开释放掉

每个结构里面声明一张map缓存格子里面所有的物体 <物体类型,map<物体uid,true>>

2.计算炸弹爆炸所影响的格子(长宽不等的十字形)

炸弹有一个威力等级Force,计算规则为 Force*2+1 = 同一轴上所影响的格子

但是碰到铁箱子是无法穿透的,所有这个爆炸的十字形可能是长宽不等的

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协议 客户端转实体)
--]]

  

转载于:https://www.cnblogs.com/cocotang/p/10825682.html

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值