随机递归生成迷宫,注意:长宽必须为奇数,不然会导致无法包围。游戏开始时生成迷宫。
local mox = {} -- 迷宫数据
local scale = 3 -- 缩放倍率:2格路+1格墙=3。如果要路和墙都2格,可以设为4
local w_logic, h_logic = 51, 51 -- 长宽
local w0, h0 = 2, 2 -- 逻辑起点
local x0, y0, z0 = 531, 7, -171 -- 生成原点(填写世界坐标)
local hh = 5 -- 迷宫高度
local id = 666 -- 墙体ID
local x, y = 0, 0
local rec = {}
local st = 0
local last = {}
local function isVisited(lx, ly)
for _, pos in ipairs(rec) do
if pos == (ly - 1) * w_logic + lx then return true end
end
return false
end
-- 获取可用方向
local function getDr()
local dr = {}
if y > 2 and not isVisited(x, y - 2) then table.insert(dr, 0) end -- 上
if x > 2 and not isVisited(x - 2, y) then table.insert(dr, 1) end -- 左
if y < h_logic - 1 and not isVisited(x, y + 2) then table.insert(dr, 2) end -- 下
if x < w_logic - 1 and not isVisited(x + 2, y) then table.insert(dr, 3) end -- 右
return #dr, dr
end
-- 初始化逻辑迷宫(全部填墙)
local function mCreat()
for i = 1, h_logic do
mox[i] = {}
for j = 1, w_logic do mox[i][j] = 1 end
end
x, y = w0, h0
mox[y][x] = 0
table.insert(rec, (y - 1) * w_logic + x)
st = 1
last[st] = {y, x}
end
-- 递归生成逻辑
local function delMo()
local c, dr = getDr()
if c > 0 then
local dir = dr[math.random(1, c)]
if dir == 0 then mox[y-1][x]=0; y=y-2
elseif dir == 1 then mox[y][x-1]=0; x=x-2
elseif dir == 2 then mox[y+1][x]=0; y=y+2
elseif dir == 3 then mox[y][x+1]=0; x=x+2 end
mox[y][x] = 0
table.insert(rec, (y - 1) * w_logic + x)
st = st + 1
last[st] = {y, x}
delMo()
elseif st > 1 then
st = st - 1
y, x = last[st][1], last[st][2]
delMo()
end
end
local ep = 0
Go = function(e)
if math.floor(e.x) == x0 then ep = 0 end
end
ScriptSupportEvent:registerEvent("Player.ClickBlock", Go)
return function()
if ep == 0 then
mCreat()
delMo()
ep = 1
elseif ep <= h_logic then
for i = 1, w_logic do
local isWall = (mox[ep][i] == 1)
-- 计算在世界中的填充区域
-- 路径占2格,墙占1格
for sx = 0, 1 do -- 宽度拉伸
for sz = 0, 1 do -- 深度拉伸
local realX = x0 + (ep - 1) * 2 + sx
local realZ = z0 - (i - 1) * 2 - sz
for h_idx = 0, hh - 1 do
Block:replaceBlock(isWall and id or 0, realX, y0 + h_idx, realZ, 0)
end
end
end
end
Chat:sendSystemMsg("生成进度: " .. ep .. "/" .. h_logic)
ep = ep + 1
elseif ep == h_logic + 1 then
Chat:sendSystemMsg("生成完毕!")
ep = -1
end
end