diff --git a/src/main.lua b/src/main.lua index 911a108..e46a97c 100644 --- a/src/main.lua +++ b/src/main.lua @@ -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