Compare commits
10
Commits
fd78174ec4
..
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a7fde20dd6 | ||
|
|
831ab54250 | ||
|
|
90fa03265a | ||
|
|
bc94ffaa54 | ||
|
|
2534e7ec59 | ||
|
|
f33d6f2428 | ||
|
|
6aad8657c9 | ||
|
|
eb0c1721da | ||
|
|
bcfadc4800 | ||
|
|
cf72109178 |
@@ -0,0 +1,4 @@
|
||||
# OrangeDream
|
||||
Eventually, it's supposed to be a survival/crafting game with space travel. Hence why it's world-shaped.
|
||||
|
||||
Using the heightmap generator from here: https://github.com/TangentFoxy/heightmap
|
||||
+47
-101
@@ -1,129 +1,75 @@
|
||||
local heightmap = require "lib.heightmap"
|
||||
local map_generator = require "map_generator"
|
||||
local lovebird = require "lib.lovebird"
|
||||
local lume = require "lib.lume"
|
||||
|
||||
local map = {}
|
||||
local map
|
||||
|
||||
love.load = function()
|
||||
map.size = 150
|
||||
map.height = 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)
|
||||
map = map_generator.generate()
|
||||
|
||||
-- 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)
|
||||
end
|
||||
end
|
||||
-- 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.altitude[x][y] / 2)
|
||||
-- end
|
||||
-- end
|
||||
-- heightmap.normalize(map.temperature, -89.2, 56.7)
|
||||
|
||||
-- modify temperature by latitude
|
||||
-- TODO would be more efficient to calculate Y in outer loop, since X does not change the distance
|
||||
-- NOTE only subtracts temperature, which further "ruins normalization" and makes everything too cold:
|
||||
local center_y = map.size / 2
|
||||
for x = 0, map.temperature.w do
|
||||
for y = 0, map.temperature.h do
|
||||
local distance = math.abs(y - center_y)
|
||||
map.temperature[x][y] = lume.clamp(map.temperature[x][y] - distance / map.size / 2, 0, 1)
|
||||
end
|
||||
end
|
||||
-- local center_y = map.size / 2
|
||||
-- for x = 0, map.temperature.w do
|
||||
-- for y = 0, map.temperature.h do
|
||||
-- local distance = math.abs(y - center_y)
|
||||
-- map.temperature[x][y] = lume.clamp(map.temperature[x][y] - distance / map.size, 0, 1)
|
||||
-- end
|
||||
-- end
|
||||
-- heightmap.normalize(map.temperature, -89.2, 56.7)
|
||||
|
||||
-- increase humidity by half temperature
|
||||
for x = 0, map.humidity.w do
|
||||
for y = 0, map.humidity.h do
|
||||
map.humidity[x][y] = math.min(1, map.humidity[x][y] + map.temperature[x][y] / 2)
|
||||
end
|
||||
end
|
||||
|
||||
-- planetizer!
|
||||
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
|
||||
end
|
||||
end
|
||||
end
|
||||
-- for x = 0, map.humidity.w do
|
||||
-- for y = 0, map.humidity.h do
|
||||
-- map.humidity[x][y] = math.min(1, map.humidity[x][y] + map.temperature[x][y] / 2)
|
||||
-- end
|
||||
-- end
|
||||
-- heightmap.normalize(map.humidity, 18, 3240)
|
||||
end
|
||||
|
||||
local camera = {
|
||||
x = 0, y = 0,
|
||||
speed = 500,
|
||||
}
|
||||
love.update = function(dt)
|
||||
lovebird.update()
|
||||
|
||||
if love.keyboard.isDown("w") then
|
||||
camera.y = camera.y - camera.speed * dt
|
||||
end
|
||||
if love.keyboard.isDown("s") then
|
||||
camera.y = camera.y + camera.speed * dt
|
||||
end
|
||||
if love.keyboard.isDown("a") then
|
||||
camera.x = camera.x - camera.speed * dt
|
||||
end
|
||||
if love.keyboard.isDown("d") then
|
||||
camera.x = camera.x + camera.speed * dt
|
||||
end
|
||||
end
|
||||
|
||||
local window_width, window_height = love.graphics.getDimensions()
|
||||
love.draw = function()
|
||||
local tile_size = 2
|
||||
love.graphics.translate(window_width / 2 - (map.size * map.tile_size) / 2 - camera.x, window_height / 2 - (map.size * map.tile_size) / 2 - camera.y)
|
||||
|
||||
for x = 0, map.height.w do
|
||||
for y = 0, map.height.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)
|
||||
|
||||
-- temperature map
|
||||
local value = map.temperature[x][y]
|
||||
love.graphics.setColor(value, 0, 0, 1)
|
||||
love.graphics.rectangle("fill", map.size * tile_size + x * tile_size, y * tile_size, tile_size, tile_size)
|
||||
|
||||
-- humidity map
|
||||
local value = map.humidity[x][y]
|
||||
love.graphics.setColor(0, 0, value, 1)
|
||||
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]
|
||||
for x = 0, map.size do
|
||||
for y = 0, map.size do
|
||||
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.rectangle("fill", map.size * tile_size + x * tile_size, map.size * tile_size + y * tile_size, tile_size, tile_size)
|
||||
love.graphics.setColor(value)
|
||||
love.graphics.rectangle("fill", x * map.tile_size, y * map.tile_size, map.tile_size, map.tile_size)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -0,0 +1,181 @@
|
||||
local heightmap = require "lib.heightmap"
|
||||
local lume = require "lib.lume"
|
||||
|
||||
local biomes = {
|
||||
-- [5] = {
|
||||
-- name = "ocean",
|
||||
-- altitude = {min = 0, max = 0.2}, -- bottom of world is the only part that matters
|
||||
-- temperature = {min = 0, max = 1},
|
||||
-- humidity = {min = 0, max = 1},
|
||||
-- color = {0, 0, 0.67, 1},
|
||||
-- },
|
||||
-- [6] = {
|
||||
-- name = "beach",
|
||||
-- altitude = {min = 0.2, max = 0.205}, -- just above ocean
|
||||
-- temperature = {min = 0, max = 1},
|
||||
-- humidity = {min = 0, max = 0.8}, -- excluding upper humidity for swamp
|
||||
-- color = {1, 1, 0.33, 1}, -- brighter yellow to distinguish from sand
|
||||
-- },
|
||||
-- [8] = {
|
||||
-- name = "swamp", -- fun idea, but generates between ocean and water too often?
|
||||
-- altitude = {min = 0, max = 1},
|
||||
-- temperature = {min = 0.5, max = 1},
|
||||
-- humidity = {min = 0.95, max = 1},
|
||||
-- color = {0, 0.5, 0.33, 1},
|
||||
-- },
|
||||
-- [10] = {
|
||||
-- name = "water",
|
||||
-- altitude = {min = 0, max = 0.9}, -- top excluded because it should've gone downhill
|
||||
-- temperature = {min = 0.1, max = 0.9}, -- bottom should be ice, top should evaporate
|
||||
-- humidity = {min = 0.8, max = 1}, -- only the wettest places
|
||||
-- color = {0, 0, 1, 1},
|
||||
-- },
|
||||
-- [20] = {
|
||||
-- name = "sand",
|
||||
-- altitude = {min = 0.2, max = 0.9}, -- top falls down, bottom is underwater
|
||||
-- temperature = {min = 0, max = 1},
|
||||
-- humidity = {min = 0, max = 0.2}, -- only where dry makes more sense for a desert
|
||||
-- color = {1, 1, 0, 1},
|
||||
-- },
|
||||
-- [30] = {
|
||||
-- name = "grass",
|
||||
-- altitude = {min = 0.3, max = 0.9}, -- top of the world not enough air, bottom too wet / leaving space for others
|
||||
-- temperature = {min = 0.2, max = 0.8}, -- not very sensitive to temperature
|
||||
-- humidity = {min = 0.2, max = 0.6}, -- not very sensitive to humidity; but excluded from the worst
|
||||
-- color = {0, 1, 0, 1},
|
||||
-- },
|
||||
-- [40] = {
|
||||
-- name = "trees",
|
||||
-- altitude = {min = 0.4, max = 0.7}, -- more sensitive than grass
|
||||
-- temperature = {min = 0, max = 0.7},
|
||||
-- humidity = {min = 0.3, max = 0.8}, -- these are not desert trees, they need more water
|
||||
-- color = {0, 0.67, 0, 1},
|
||||
-- },
|
||||
-- [60] = {
|
||||
-- name = "stone",
|
||||
-- altitude = {min = 0, max = 1},
|
||||
-- temperature = {min = 0, max = 1},
|
||||
-- humidity = {min = 0, max = 1},
|
||||
-- color = {0.67, 0.67, 0.67, 1},
|
||||
-- },
|
||||
-- [50] = {
|
||||
-- name = "ice",
|
||||
-- altitude = {min = 0, max = 1},
|
||||
-- temperature = {min = 0, max = 0.01},
|
||||
-- humidity = {min = 0.2, max = 1},
|
||||
-- color = {1, 1, 1, 1},
|
||||
-- },
|
||||
[900] = {
|
||||
name = "deep ocean",
|
||||
altitude = {min = -math.huge, max = -5000},
|
||||
temperature = {min = -math.huge, max = math.huge},
|
||||
humidity = {min = -math.huge, max = math.huge},
|
||||
color = {0, 0, 0.25, 1},
|
||||
},
|
||||
[1000] = {
|
||||
name = "ocean (definition, 0 meters)",
|
||||
altitude = {min = -math.huge, max = 0},
|
||||
temperature = {min = -math.huge, max = math.huge},
|
||||
humidity = {min = -math.huge, max = math.huge},
|
||||
color = {0, 0, 0.5, 1},
|
||||
},
|
||||
[2000] = {
|
||||
name = "snowline (middle estimate)",
|
||||
altitude = {min = 4000, max = math.huge},
|
||||
temperature = {min = -math.huge, max = math.huge},
|
||||
humidity = {min = -math.huge, max = math.huge},
|
||||
color = {1, 1, 1, 1},
|
||||
},
|
||||
[2100] = {
|
||||
name = "alpine zone",
|
||||
altitude = {min = 3500, max = math.huge},
|
||||
temperature = {min = -math.huge, max = math.huge},
|
||||
humidity = {min = -math.huge, max = math.huge},
|
||||
color = {0.8, 0.8, 0.8, 1},
|
||||
},
|
||||
[2200] = {
|
||||
name = "subalpine zone",
|
||||
altitude = {min = 3000, max = math.huge},
|
||||
temperature = {min = -math.huge, max = math.huge},
|
||||
humidity = {min = -math.huge, max = math.huge},
|
||||
color = {0.67, 0.67, 0.67, 1},
|
||||
},
|
||||
[2300] = {
|
||||
name = "montane zone",
|
||||
altitude = {min = 2500, max = math.huge},
|
||||
temperature = {min = -math.huge, max = math.huge},
|
||||
humidity = {min = -math.huge, max = math.huge},
|
||||
color = {0.67, 0.67, 0.5, 1},
|
||||
},
|
||||
}
|
||||
|
||||
local function generate()
|
||||
local map = {}
|
||||
|
||||
map.size = 500
|
||||
map.tile_size = 1
|
||||
map.altitude = heightmap.create(map.size, map.size, 0, 1) -- meters
|
||||
map.temperature = heightmap.create(map.size, map.size, -89.2, 56.7) -- celsius
|
||||
map.humidity = heightmap.create(map.size, map.size, 18, 3240) -- millimeters rainfall
|
||||
|
||||
-- local function earthlike_altitude_adjustment(altitude)
|
||||
-- -- max too low, min too high, too much ocean
|
||||
-- return 6099 - 114909 * altitude + 830891 * altitude^2 - 2.72e6 * altitude^3 + 4.19e6 * altitude^4 - 3.02e6 * altitude^5 + 815866 * altitude^6
|
||||
-- end
|
||||
local function earthlike_altitude_adjustment(altitude)
|
||||
-- good oceans, too much high altitude
|
||||
return -10948 + 101018 * altitude - 643382 * altitude^2 + 2.17e6 * altitude^3 - 3.62e6 * altitude^4 + 2.87e6 * altitude^5 -852042 * altitude^6
|
||||
end
|
||||
-- local function earthlike_altitude_adjustment(altitude)
|
||||
-- -- only creates ocean (wtf)
|
||||
-- return -10851 + 151279 * altitude - 1.14e6 * altitude^2 +3.84e6 * altitude^3 -6.11e6 * altitude^4 +4.48e6 * altitude^5 - 1.21e6 * altitude^6
|
||||
-- end
|
||||
local min, max = math.huge, -math.huge
|
||||
for x = 0, map.size do
|
||||
for y = 0, map.size do
|
||||
local value = earthlike_altitude_adjustment(map.altitude[x][y])
|
||||
if value > max then max = value end
|
||||
if value < min then min = value end
|
||||
map.altitude[x][y] = value
|
||||
end
|
||||
end
|
||||
print("Altitude", "Min: ", min, "Max:", max)
|
||||
|
||||
-- planetizer!
|
||||
local biome_order = {}
|
||||
for order in pairs(biomes) do
|
||||
biome_order[#biome_order + 1] = order
|
||||
end
|
||||
table.sort(biome_order)
|
||||
|
||||
map.terrain = {w = map.size, h = map.size}
|
||||
local radius = (map.size / 2)^2
|
||||
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 _, biome in ipairs(biomes) do
|
||||
for _, order in ipairs(biome_order) do
|
||||
local biome = biomes[order]
|
||||
local altitude = map.altitude[x][y]
|
||||
if altitude >= biome.altitude.min and altitude <= biome.altitude.max then
|
||||
local temperature = map.temperature[x][y]
|
||||
if temperature >= biome.temperature.min and temperature <= biome.temperature.max then
|
||||
local humidity = map.humidity[x][y]
|
||||
if humidity >= biome.humidity.min and humidity <= biome.humidity.max then
|
||||
map.terrain[x][y] = biome.color
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return map
|
||||
end
|
||||
|
||||
return {
|
||||
generate = generate,
|
||||
}
|
||||
Reference in New Issue
Block a user