首页 > 解决方案 > 如何改进我的 RBX.Lua 程序生成代码?

问题描述

这是我在堆栈溢出中的第一篇文章,我不知道我是否可以在这里发布有关 roblox 开发的内容。

但无论如何,我走了。我正在制作一个自上而下的像素艺术生存游戏,并在程序上生成具有许多不同生物群落的“平面”世界。代码运行良好,只是结果看起来真的很不自然,我不知道该怎么办。

我的意思的一些例子: 世界1世界2世界3

这是我的代码:

local biomeInfo = require(script.BiomeInfo)

local heightSeed = math.random(-2147483640, 2147483640)
local moistureSeed = math.random(-2147483640, 2147483640)
local heatSeed = math.random(-2147483640, 2147483640)

local mapSize = 250
local resolution = 20
local frequency = 15
local amplitude = 95

-- Generate noise maps
local grid = {}
for x = 1, mapSize do
    grid[x] = {}

    for z = 1, mapSize do
        local heightMap = math.noise(x / resolution * frequency / amplitude, z / resolution * frequency / amplitude, heightSeed)
        local moistureMap = math.noise(x / resolution * frequency / amplitude, z / resolution * frequency / amplitude, moistureSeed)
        local heatMap = math.noise(x / resolution * frequency / amplitude, z / resolution * frequency / amplitude, heatSeed)

        --[[local heightMap = math.noise(x / resolution * 1.2 / 3.2, z / resolution * 1.2 / 3.2, heightSeed)
        local moistureMap = math.noise(x / resolution * 4 / 5.6, z / resolution * 4 / 5.6, moistureSeed)
        local heatMap = math.noise(x / resolution * 2.7 / 7, z / resolution * 2.7 / 7, heatSeed)]]

        grid[x][z] = {
            ["Height"] = math.clamp(heightMap, -0.5, 0.5) + 0.5,
            ["Moisture"] = math.clamp(moistureMap, -0.5, 0.5) + 0.5,
            ["Heat"] = math.clamp(heatMap, -0.5, 0.5) + 0.5,
        }
    end
end

-- Generate blocks
for x = 1, mapSize do
    for z = 1, mapSize do
        
        -- Get all available biomes for this block
        local availableBiomes = {}
        for name, value in pairs(biomeInfo) do
            local condition = grid[x][z]["Height"] >= biomeInfo[name]["Height"] and grid[x][z]["Moisture"] >= biomeInfo[name]["Moisture"] and grid[x][z]["Heat"] >= biomeInfo[name]["Heat"]
            if condition and not availableBiomes[name] then
                table.insert(availableBiomes, name)
            end
        end
        
        -- Calculate value differences for all available biomes for this block
        local valueDiffs = {}
        for _, biome in pairs(availableBiomes) do
            valueDiffs[biome] = (grid[x][z]["Height"] - biomeInfo[biome]["Height"]) + (grid[x][z]["Moisture"] - biomeInfo[biome]["Moisture"]) + (grid[x][z]["Heat"] - biomeInfo[biome]["Heat"])
        end
        
        -- Get the lowest value difference, assign the corresponding biome
        local lowestValue = 1
        local selectedBiome
        for biome, value in pairs(valueDiffs) do
            if value < lowestValue then
                lowestValue = value
                selectedBiome = biome
            end
        end
        
        -- Generate the block
        local block = Instance.new("Part")
        block.Anchored = true
        block.Size = Vector3.new(8, 8, 8)
        block.Position = Vector3.new(x * 8, 0, z * 8)
        block.Parent = game.Workspace.World
        if grid[x][z]["Height"] <= 0.2 then -- Water level
            block.BrickColor = BrickColor.new("Electric blue")
        elseif selectedBiome == "Grasslands" then
            block.BrickColor = BrickColor.new("Bright green")
        elseif selectedBiome == "Taiga" then
            block.BrickColor = BrickColor.new("Baby blue")
        elseif selectedBiome == "Desert" then
            block.BrickColor = BrickColor.new("Cool yellow")
        elseif selectedBiome == "Swamp" then
            block.BrickColor = BrickColor.new("Slime green")
        elseif selectedBiome == "Mountains" then
            block.BrickColor = BrickColor.new("Dark stone grey")
        elseif selectedBiome == "Jungle" then
            block.BrickColor = BrickColor.new("Earth green")
        elseif selectedBiome == "Snowy tundra" then
            block.BrickColor = BrickColor.new("White")
        else
            block.BrickColor = BrickColor.new("Bright green")
        end

        block.Position = Vector3.new(x * 8, 4.5, z * 8)
        block.Parent = game.Workspace.World
    end
    game:GetService("RunService").Heartbeat:Wait()
end

注意:我知道许多 elseif 语句效率低下,这是暂时的,请忽略它。

“BiomeInfo”模块脚本:

return {
    ["Grasslands"] = {
        ["Height"] = 0.27,
        ["Moisture"] = 0.21,
        ["Heat"] = 0.25
    },
    ["Desert"] = {
        ["Height"] = 0.15,
        ["Moisture"] = 0.05,
        ["Heat"] = 0.49
    },
    ["Taiga"] = {
        ["Height"] = 0.28,
        ["Moisture"] = 0.16,
        ["Heat"] = 0.12
    },
    ["Swamp"] = {
        ["Height"] = 0.16,
        ["Moisture"] = 0.44,
        ["Heat"] = 0.14
    },
    ["Mountains"] = {
        ["Height"] = 0.43,
        ["Moisture"] = 0.08,
        ["Heat"] = 0.11
    },
    ["Jungle"] = {
        ["Height"] = 0.22,
        ["Moisture"] = 0.51,
        ["Heat"] = 0.31
    },
    ["Snowy tundra"] = {
        ["Height"] = 0.17,
        ["Moisture"] = 0.12,
        ["Heat"] = 0.03
    },
}

这是我第一次使用程序生成,所以我不确定我是否对所有事情都应用了最有效的方法。

标签: luarobloxprocedural-generation

解决方案


推荐阅读