200字
迷你世界仿柏林噪声地形生成
2026-01-31
2026-01-31
-- 柏林噪声函数by<a>ink芯<a>
local function interpolate(a, b, t)
    return a + t * (b - a)
end

local function randomGradient(x, y)
    local hash = (x * 12345 + y * 67890) % 10000
    local angle = (hash / 10000) * 2 * math.pi
    return math.cos(angle), math.sin(angle)
end

local function dotGradient(ix, iy, x, y)
    local dx = x - ix
    local dy = y - iy
    local gx, gy = randomGradient(ix, iy)
    return dx * gx + dy * gy
end

-- 2D柏林噪声函数
local function perlinNoise(x, y)
    local ix = math.floor(x)
    local iy = math.floor(y)
    local fx = x - ix
    local fy = y - iy

    local u = fx * fx * fx * (fx * (fx * 6 - 15) + 10)
    local v = fy * fy * fy * (fy * (fy * 6 - 15) + 10)

    local n0 = dotGradient(ix, iy, x, y)
    local n1 = dotGradient(ix + 1, iy, x, y)
    local n2 = dotGradient(ix, iy + 1, x, y)
    local n3 = dotGradient(ix + 1, iy + 1, x, y)

    local x1 = interpolate(n0, n1, u)
    local x2 = interpolate(n2, n3, u)
    return interpolate(x1, x2, v)
end

-- 分形布朗运动(多倍频噪声叠加)
local function fbm(x, y, octaves, persistence, lacunarity)
    local total = 0
    local amplitude = 1
    local frequency = 1
    local maxValue = 0

    for i = 1, octaves do
        total = total + perlinNoise(x * frequency, y * frequency) * amplitude
        maxValue = maxValue + amplitude
        amplitude = amplitude * persistence
        frequency = frequency * lacunarity
    end

    return total / maxValue -- 归一化到[-1,1]
end

-- 地形生成主函数(移除水方块,替换为泥土)
local function generateTerrain(playerObjid)
    -- 获取玩家当前位置
    local _, px, py, pz = Player:getPosition(playerObjid)
    px = math.floor(px)
    pz = math.floor(pz)
    local baseY = math.floor(py) -- 地形基准高度

    Chat:sendSystemMsg("正在生成无水域柏林噪声地形...")

    -- 生成31x31范围地形(中心在玩家位置)
    local range = 15
    for x = -range, range do
        for z = -range, range do
            -- 计算噪声值(4倍频,提升细节)
            local noise = fbm((px + x) / 20, (pz + z) / 20, 4, 0.5, 2.0)
            -- 映射噪声值到地形高度(-1→baseY-3,1→baseY+5)
            local terrainY = baseY + math.floor(noise * 4 + 1)

            -- 放置方块(移除水方块,低地改为泥土)
            if terrainY >= baseY + 3 then
                -- 高山:石头(ID:104)
                Block:setBlockAll(px + x, terrainY, pz + z, 104, 0)
                -- 山底:基岩(ID:1)
                Block:setBlockAll(px + x, terrainY - 1, pz + z, 1, 0)
            elseif terrainY >= baseY then
                -- 平地:草块(ID:2)
                Block:setBlockAll(px + x, terrainY, pz + z, 2, 0)
                -- 地下:泥土(ID:101)
                for dy = 1, 2 do
                    Block:setBlockAll(px + x, terrainY - dy, pz + z, 101, 0)
                end
            else
                -- 低地:泥土(替换原水方块,ID:101)
                Block:setBlockAll(px + x, terrainY, pz + z, 101, 0)
                -- 地下:1层泥土地基
                Block:setBlockAll(px + x, terrainY - 1, pz + z, 101, 0)
            end
        end
    end

    Chat:sendSystemMsg("无水域地形生成完成!范围:" .. (range * 2 + 1) .. "x" .. (range * 2 + 1))
end

-- 监听玩家使用道具事件
local function onPlayerUseItem(event)
    local itemid = event.itemid
    local playerObjid = event.eventobjid

    -- 仅当使用石剑(ID:12012)时触发
    if itemid == 12012 then
        generateTerrain(playerObjid)
    end
end

-- 注册事件
ScriptSupportEvent:registerEvent([=[Player.UseItem]=], onPlayerUseItem)

迷你世界脚本2.0

迷你世界仿柏林噪声地形生成
作者
114514s
发表于
2026-01-31

评论