参考:http://www.jb51.cc/article/p-ktsijnyd-xn.html
1.填充地图
2.挖空需要访问的所有点
3.设置起始点
4.开始访问
4.1获取当前点4个方向上的可访问且没有访问过的点
4.2随机选择其中一个点进行访问,并设置为当前访问点,将该点加入已访问列表,同时挖空2个点之间的所有点
4.3如果当前点各个方向上都没有可访问的点,那么从之前访问过的点里随机选取一个点作为当前访问点,并重复以上步骤
5.如果所有点都已被访问过,结束,随机地图完成
代码
--[[随机迷宫地图生成类--]]local RandMazeMap = class("RandMazeMap")RandMazeMap._instance = nilRandMazeMap._tmx = nilRandMazeMap._emptyID = nilRandMazeMap._fullID = nilRandMazeMap._mapSize = nilRandMazeMap._curPos = nilRandMazeMap._toVisit ={} -- 用于位置直接索引RandMazeMap._toVisitList = {} -- 用于列表序号索引RandMazeMap._visited = {} -- 用于索引记录已访问过的点的索引 主要是方便从已访问的里面取随机点用function RandMazeMap.GetInstance() if RandMazeMap._instance == nil then RandMazeMap._instance = RandMazeMap.new() end return RandMazeMap._instanceendfunction RandMazeMap.ReleaseInstance() if RandMazeMap._instance ~= nil then RandMazeMap._instance:Release() RandMazeMap._instance = nil endend-- 初始化 读取tmx 获取迷宫总大小function RandMazeMap:Init(tmx,randomSeed) if randomSeed == nil then randomSeed = os.time() end math.randomseed(randomSeed) self._tmx = tmx self._emptyID = self._tmx:getLayer("Pass"):getTileGIDAt(cc.p(0,0)) self._fullID = self._tmx:getLayer("NotPass"):getTileGIDAt(cc.p(0,0)) self._mapSize = self._tmx:getMapSize()end-- 生成随机地图function RandMazeMap:MakeRandMaze(toVisit,firstVisited) -- 生成开始 -- 地图填满 self:FillMap() -- 设置必须经过的点 置0 self:SetToVisit(toVisit) -- 挖空需要访问的点 self:VisitAll() -- 设置初始点 self:SetFirstVisited(firstVisited) -- 制作访问图 self:DoVisitAll() -- 生成完毕endfunction RandMazeMap:FillMap() for w=0,self._mapSize.wIDth-1 do for h=0,self._mapSize.height-1 do self._tmx:getLayer("Pass"):setTileGID(self._emptyID,cc.p(w,h)) self._tmx:getLayer("NotPass"):setTileGID(self._fullID,h)) end endendfunction RandMazeMap:SetToVisit(toVisit) if toVisit == nil then -- 内部所有点都访问一遍 self._toVisit = {} self._toVisitList = {} for w=0,self._mapSize.wIDth-1 do for h=0,self._mapSize.height-1 do if w%2 == 1 and h%2 == 1 and w ~= self._mapSize.wIDth-1 and h ~= self._mapSize.height-1 then self:AddToVisit(w,h) end end end else -- self._toVisit = toVisit endendfunction RandMazeMap:AddToVisit(x,y) -- 检查位置合法性 table.insert(self._toVisitList,cc.p(x,y)) if self._toVisit[x] == nil then self._toVisit[x] = {} end self._toVisit[x][y] = {isVisited = false,index = #self._toVisitList}endfunction RandMazeMap:VisitAll() for k,v in pairs(self._toVisitList) do self:MakeHole(v) endendfunction RandMazeMap:MakeHole(pos) self._tmx:getLayer("NotPass"):setTileGID(0,pos)endfunction RandMazeMap:SetFirstVisited(firstVisited) self._visited = {} if firstVisited == nil then -- 没有指定 则随机选一个 firstVisited = math.random(#self._toVisitList) end self:SetVisited(firstVisited)endfunction RandMazeMap:SetVisited(visitedindex,isNewVisit) if isNewVisit == nil then isNewVisit = true end -- 检查位置合法性 local curPos = self._curPos local visitedPos = self._toVisitList[visitedindex] self._curPos = visitedPos self._toVisit[visitedPos.x][visitedPos.y].isVisited = true if not isNewVisit then -- 非新添加 直接跳过下面的 *** 作 return end -- 记录添加到已访问表中 table.insert(self._visited,visitedindex) -- 处理ui界面部分 -- 2点中间的所有单元都挖空 if curPos ~= nil then self:MakelineHole(curPos,self._curPos) endendfunction RandMazeMap:MakelineHole(posst,posEd) local offset = cc.pSub(posst,posEd) local holePos = posst if offset.x < 0 then -- 向右 for i=1,-offset.x do holePos = cc.pAdd(holePos,cc.p(1,0)) self:MakeHole(holePos) end elseif offset.x > 0 then -- 向左 for i=1,offset.x do holePos = cc.pAdd(holePos,cc.p(-1,0)) self:MakeHole(holePos) end elseif offset.y < 0 then -- 向上 for i=1,-offset.y do holePos = cc.pAdd(holePos,cc.p(0,1)) self:MakeHole(holePos) end elseif offset.y > 0 then -- 向下 for i=1,offset.y do holePos = cc.pAdd(holePos,-1)) self:MakeHole(holePos) end endendfunction RandMazeMap:DoVisitAll() local dirOffset = { cc.p(-2,0),cc.p(2,-2),2) } while #self._visited < #self._toVisitList do -- 获取各个方向相邻的访问点 local nearPoses = {} for i=1,#dirOffset do local newPos = cc.pAdd(self._curPos,dirOffset[i]) -- 添加~=nil判断 防止访问边界外的无效单元 if self._toVisit[newPos.x] ~= nil and self._toVisit[newPos.x][newPos.y] ~= nil and not self._toVisit[newPos.x][newPos.y].isVisited then table.insert(nearPoses,self._toVisit[newPos.x][newPos.y].index) end end if #nearPoses > 0 then -- 存在没有访问过的点 -- 随机方向 local index = math.random(#nearPoses) -- 设置当前访问点 self:SetVisited(nearPoses[index]) else -- 各方向都已访问 随机直接取已访问过的点作为当前点 并重新访问 local index = math.random(#self._visited) visitedindex = self._visited[index] self:SetVisited(visitedindex,false) end endendreturn RandMazeMap总结
以上是内存溢出为你收集整理的【cocos2dx 3.3 lua】08 随机迷宫生成全部内容,希望文章能够帮你解决【cocos2dx 3.3 lua】08 随机迷宫生成所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)