biomes defined in a better structure

This commit is contained in:
2026-07-19 08:13:30 -06:00
parent fd78174ec4
commit cf72109178
+54 -59
View File
@@ -4,35 +4,49 @@ local lume = require "lib.lume"
local map = {}
local biomes = {
water = {
altitude = {min = 0, max = 0.2},
color = {0, 0, 1, 1},
},
sand = {
altitude = {min = 0.2, max = 0.215},
color = {1, 1, 0, 1},
},
grass = {
altitude = {min = 0.215, max = 0.34},
color = {0, 1, 0, 1},
},
trees = {
altitude = {min = 0.34, max = 0.72},
color = {0, 0.67, 0, 1},
},
stone = {
altitude = {min = 0.72, max = 0.9},
color = {0.67, 0.67, 0.67, 1},
},
ice = {
altitude = {min = 0.9, max = 1},
color = {1, 1, 1, 1}
},
}
love.load = function()
map.size = 150
map.height = heightmap.create(map.size, map.size, 0, 1)
map.altitude = heightmap.create(map.size, map.size, 0, 1)
map.temperature = heightmap.create(map.size, map.size, 0, 1)
map.humidity = heightmap.create(map.size, map.size, 0, 1)
-- weird mixing idea test
-- why does this average things out?
-- trying to renormalize it now..
local temporary_maps = {}
for i = 1, 3 do
temporary_maps[i] = heightmap.create(map.size, map.size, 0, 1)
end
for x = 0, map.height.w do
for y = 0, map.height.h do
map.height[x][y] = (map.height[x][y] + temporary_maps[1][x][y] + temporary_maps[2][x][y] + temporary_maps[3][x][y] ) / 4
end
end
heightmap.normalize(map.height, 0, 1)
-- if true then return end
-- lower temperature by half height
-- NOTE ruins "normalization" but that's fine once we have "real" numbers to work with
for x = 0, map.temperature.w do
for y = 0, map.temperature.h do
map.temperature[x][y] = math.max(0, map.temperature[x][y] - map.height[x][y] / 2)
map.temperature[x][y] = math.max(0, map.temperature[x][y] - map.altitude[x][y] / 2)
end
end
heightmap.normalize(map.temperature, 0, 1)
-- modify temperature by latitude
-- TODO would be more efficient to calculate Y in outer loop, since X does not change the distance
@@ -44,6 +58,7 @@ love.load = function()
map.temperature[x][y] = lume.clamp(map.temperature[x][y] - distance / map.size / 2, 0, 1)
end
end
heightmap.normalize(map.temperature, 0, 1)
-- increase humidity by half temperature
for x = 0, map.humidity.w do
@@ -53,11 +68,21 @@ love.load = function()
end
-- planetizer!
map.terrain = {}
local radius = (map.size / 2)^2
for x = 0, map.height.w do
for y = 0, map.height.h do
if lume.distance(x, y, map.size / 2, map.size / 2, true) > radius then
map.height[x][y] = nil
for x = 0, map.size do
map.terrain[x] = {}
for y = 0, map.size do
if lume.distance(x, y, map.size / 2, map.size / 2, true) < radius then
for name, biome in pairs(biomes) do
local value = map.altitude[x][y]
-- this allows a non-deterministic change of terrain
-- depending on which biome is checked first but I don't care right now]
if value >= biome.altitude.min and value <= biome.altitude.max then
map.terrain[x][y] = biome.color
break
end
end
end
end
end
@@ -70,31 +95,14 @@ end
love.draw = function()
local tile_size = 2
for x = 0, map.height.w do
for y = 0, map.height.h do
for x = 0, map.altitude.w do
for y = 0, map.altitude.h do
-- raw heightmap
-- NOTE will break with planetizer enabled!
-- local value = map.height[x][y]
-- love.graphics.setColor(value, value, value, 1)
-- love.graphics.rectangle("fill", x * tile_size, y * tile_size, tile_size, tile_size)
-- even weighting between height and temperature
-- local value = map.height[x][y] / 2 + map.temperature[x][y] / 2
-- if value < 0.2 then
-- love.graphics.setColor(0, 0, 1, 1)
-- elseif value < 0.215 then
-- love.graphics.setColor(1, 1, 0, 1)
-- elseif value < 0.34 then
-- love.graphics.setColor(0, 1, 0, 1)
-- elseif value < 0.72 then
-- love.graphics.setColor(0, 0.67, 0, 1)
-- elseif value < 0.9 then
-- love.graphics.setColor(0.67, 0.67, 0.67, 1)
-- else
-- -- love.graphics.setColor(0, 0, 0, 1) -- temporary nothing
-- love.graphics.setColor(1, 1, 1, 1)
-- end
-- love.graphics.rectangle("fill", x * tile_size, y * tile_size, tile_size, tile_size)
local value = map.altitude[x][y]
if value then
love.graphics.setColor(value, value, value, 1)
love.graphics.rectangle("fill", x * tile_size, y * tile_size, tile_size, tile_size)
end
-- temperature map
local value = map.temperature[x][y]
@@ -107,22 +115,9 @@ love.draw = function()
love.graphics.rectangle("fill", x * tile_size, map.size * tile_size + y * tile_size, tile_size, tile_size)
-- "naive" biomed map
local value = map.height[x][y]
local value = map.terrain[x][y]
if value then
if value < 0.2 then
love.graphics.setColor(0, 0, 1, 1)
elseif value < 0.215 then
love.graphics.setColor(1, 1, 0, 1)
elseif value < 0.34 then
love.graphics.setColor(0, 1, 0, 1)
elseif value < 0.72 then
love.graphics.setColor(0, 0.67, 0, 1)
elseif value < 0.9 then
love.graphics.setColor(0.67, 0.67, 0.67, 1)
else
-- love.graphics.setColor(0, 0, 0, 1) -- temporary nothing
love.graphics.setColor(1, 1, 1, 1)
end
love.graphics.setColor(value)
love.graphics.rectangle("fill", map.size * tile_size + x * tile_size, map.size * tile_size + y * tile_size, tile_size, tile_size)
end
end