Skip to content

Instantly share code, notes, and snippets.

@Domiii
Created August 29, 2018 11:50
Show Gist options
  • Save Domiii/c878b4f01ee0d5e029b1f1756518d2e9 to your computer and use it in GitHub Desktop.
Save Domiii/c878b4f01ee0d5e029b1f1756518d2e9 to your computer and use it in GitHub Desktop.
--[[
Steps:
1. Use an editor to create a pixel map (e.g. https://www.piskelapp.com/)
1b. If your editor cannot export BMP files, use an online converter to generate a BMP file (e.g. https://image.online-convert.com/convert-to-bmp)
2. Convert BMP to Lua here: https://codepen.io/Domiii/pen/oMJvoJ?editors=0010
3. Copy the final Lua code to workspace.LevelPixels (ModuleScript)
4. Fix configuration below: make sure that colors map to blocks that have been prepared
5. Run this script!
]]
local BlockSize = 4
local ignore = 0xFFFFFF -- white
local x = 0
local origin = Vector3.new(0, 0, 0)
local BlockPrefabFolder = 'Blocks'
local LevelBlockFolder = 'Level'
local PixelScript = workspace.LevelPixels
local PixelMap = {}
PixelMap[0x000000] = 'Grass' -- Black
PixelMap[0xFF0000] = 'Concrete' -- Red
local levelBlocks = workspace:FindFirstChild(LevelBlockFolder)
if levelBlocks then
levelBlocks:Destroy()
end
levelBlocks = Instance.new('Folder')
levelBlocks.Name = LevelBlockFolder
levelBlocks.Parent = workspace
local Blocks = workspace[BlockPrefabFolder]
local BlocksByPixel = {}
for pixelValue, name in pairs(PixelMap) do
local block = Blocks:FindFirstChild(name)
if not block then
error('Invalid block name: ' .. name)
end
BlocksByPixel[pixelValue] = block
end
local pixels = require(PixelScript:Clone())
local w = #pixels[1]
local h = #pixels
function GenerateMap()
for j = 1, h do
for i = 1, w do
--local size = Vector3.new(Amount*Amount-(i*10),Y*(i*2),Amount*Amount-(i*10))
--local pos = pos + Vector3.new(i * VoxelSize, k*VoxelSize, j*VoxelSize)
local px = pixels[j][i]
if px ~= ignore then
local pos = origin + Vector3.new(x, (h-j)*BlockSize, (w-i)*BlockSize)
local block = BlocksByPixel[px]:Clone()
block.Parent = levelBlocks
block.Position = pos
end
end
end
end
GenerateMap()
return;
-- local cancelName = 'TerrainCancel'
-- local guiName = 'TerrainGenStatusGui'
-- local cancelledRef
-- local gui
-- local statusLabel
-- function Cleanup()
-- if game.StarterGui:FindFirstChild(guiName) then
-- game.StarterGui:FindFirstChild(guiName):Destroy()
-- end
-- if workspace:FindFirstChild(cancelName) then
-- workspace:FindFirstChild(cancelName):Destroy()
-- end
-- end
-- function GetProgressPercent(current, max)
-- return current / max * 100
-- end
-- function UpdateStatus(current, max)
-- local progressPct = GetProgressPercent(current, max)
-- statusLabel.Text = tostring(math.floor(progressPct + 0.5)) .. '%'
-- end
-- function ShowTerrainGui()
-- gui = Instance.new('ScreenGui')
-- gui.Name = guiName
-- statusLabel = Instance.new('TextLabel')
-- statusLabel.Parent = gui
-- statusLabel.Size = UDim2.new(1, 0, 0, 30)
-- gui.Parent = game.StarterGui
-- cancelledRef = workspace:FindFirstChild(cancelName)
-- if not cancelledRef then
-- cancelledRef = Instance.new('BoolValue')
-- cancelledRef.Name = cancelName
-- cancelledRef.Parent = workspace
-- end
-- cancelledRef.Value = false
-- -- select the Cancel object
-- local select = { cancelledRef }
-- game.Selection:Set(select)
-- end
-- function CheckCancel()
-- if cancelledRef and cancelledRef.Value then
-- print('Terrain Generation Cancelled')
-- Cleanup()
-- return true
-- end
-- return false
-- end
-- function GetMaterial(yNormalized)
-- local material
-- if yNormalized < 0.4 then
-- material = Enum.Material.Grass
-- elseif yNormalized < 0.8 then
-- material = Enum.Material.Rock
-- else
-- material = Enum.Material.Snow
-- end
-- return material
-- end
-- function GenTerrainFromHeightmap(origin)
-- Cleanup()
-- ShowTerrainGui()
-- for i = 1, xLen, Resolution do
-- local row = pixels[i]
-- for j = 1, zLen, Resolution do
-- local px = row[j]
-- local yNormalized = px / MaxPixelValue
-- local material = GetMaterial(yNormalized)
-- y = yNormalized * MaxHeight
-- --for k = 1, y do
-- local pos = origin + Vector3.new(i*VoxelSize, 0, j*VoxelSize)
-- local size = Vector3.new(VoxelSize, y * VoxelSize, VoxelSize)
-- game.Workspace.Terrain:FillBlock(CFrame.new(pos), size, material)
-- --end
-- end
-- if CheckCancel() then return end
-- UpdateStatus(i, xLen)
-- wait()
-- end
-- print('Terrain Generation Finished!')
-- Cleanup()
-- end
-- --GenTerrainFromHeightmap(origin, pixels)
-- --GenerateMountain(origin, xLen, zLen, height)
-- function GenTerrainBetweenParts(basePart)
-- Cleanup()
-- ShowTerrainGui()
-- workspace.Terrain:Clear()
-- local material = Enum.Material.Grass
-- local size = basePart.Size
-- local pos1 = basePart.Position - size / 2
-- local pos2 = pos1 + size
-- local y = basePart.Position.Y + size.Y
-- --local y = (pos1.Y + pos2.Y) / 2
-- local up = Vector3.new(0, 1, 0)
-- for z = pos1.Z, pos2.Z do
-- for x = pos1.X, pos2.X do
-- local origin = Vector3.new(x, y, z)
-- local ray = Ray.new(origin, origin + up * 100000)
-- local terrainCellsAreCubes = false
-- local ignoreWater = true
-- local part, pos, normal, material2 = workspace:FindPartOnRay (
-- ray,
-- basePart,
-- terrainCellsAreCubes,
-- ignoreWater
-- )
-- --print(x,y,z, part, pos, normal, material2)
-- -- local p = Instance.new('Part')
-- -- p.Shape = Enum.PartType.Ball
-- -- p.Position = origin
-- -- p.Parent = workspace.Tmp
-- --if part then
-- local blockSize = Vector3.new(1, (pos - origin).Y, 1)
-- -- NOTE: basePos is the center of the block!
-- local basePos = origin + blockSize/2
-- game.Workspace.Terrain:FillBlock(CFrame.new(basePos), blockSize, material)
-- --end
-- end
-- if CheckCancel() then return end
-- UpdateStatus(z-pos1.Z, pos2.Z-pos1.Z)
-- wait()
-- end
-- print('Terrain Generation Finished!')
-- Cleanup()
-- end
-- GenTerrainBetweenParts(workspace.Baseplate)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment