local tex = love.graphics.newImage("circle.png") tex:setFilter("nearest", "nearest") local function water_color(layer) local value = layer / 24 return value / 4, value / 2, value end local function dirt_color(layer) if layer < 32 then return layer / 40 / 2.5, layer / 80 / 2.5, 0.1 else return 0.05, (layer - 32) / 36 + 0.3, 0.05 end end local function mountain_color(layer) if layer < 58 then local value = layer / 64 / 2.5 return value, value, value else local value = (layer - 58) / 20 + 0.7 return value, value, value end end local function pick_colorfn(maxlayer) if maxlayer < 16 then return water_color elseif maxlayer < 46 then return dirt_color else return mountain_color end end local function ease(n) return 5 ^ (3.1 * (n ^ 0.3) - 3) + 1 - 1.1 ^ n end local BIG_BLOCK = love.graphics.newQuad(0, 0, 8, 8, tex) local z = require("zprite").zchunk.new(tex, 128, 32) local function update_map() z:clear() for i = -160, 160 do for j = -160, 160 do local noise_value = love.math.simplexNoise(i * 0.008, j * 0.008) local layers = ease(noise_value) * 64 z:put(i * 8, j * 8, BIG_BLOCK, math.floor(layers) + 1, pick_colorfn(layers)) coroutine.yield() end end end local co = coroutine.create(update_map) local x = 0 local y = 0 local angle = 0 local scale = 1 function love.update(dt) for _ = 1, 64 do if coroutine.status(co) == "suspended" then coroutine.resume(co) end end if love.keyboard.isDown("d") then local dx = 256 * math.cos(-angle) local dy = 256 * math.sin(-angle) x = x - dx * dt y = y - dy * dt end if love.keyboard.isDown("a") then local dx = 256 * math.cos(-angle) local dy = 256 * math.sin(-angle) x = x + dx * dt y = y + dy * dt end if love.keyboard.isDown("s") then local dx = 256 * math.cos(-angle + math.pi / 2) local dy = 256 * math.sin(-angle + math.pi / 2) x = x - dx * dt y = y - dy * dt end if love.keyboard.isDown("w") then local dx = 256 * math.cos(-angle + math.pi / 2) local dy = 256 * math.sin(-angle + math.pi / 2) x = x + dx * dt y = y + dy * dt end if love.keyboard.isDown("q") then angle = angle + dt end if love.keyboard.isDown("e") then angle = angle - dt end if love.keyboard.isDown("f") then scale = scale - dt * 5 if scale < 0.2 then scale = 0.2 end end if love.keyboard.isDown("r") then scale = scale + dt * 5 if scale > 5 then scale = 5 end end end local t = love.math.newTransform() function love.draw() for _, chunk in pairs(z._chunks) do chunk.z._height_scale = 12 * scale end t:reset() t:translate(love.graphics.getWidth() / 2, love.graphics.getHeight() / 2) t:scale(scale, scale) t:rotate(angle) t:translate(x, y) z:draw(t) end