Explorinator9000/main.lua

165 lines
3.4 KiB
Lua

local tex = love.graphics.newImage("atlas.png")
tex:setFilter("nearest", "nearest")
local function water_color(layer)
local value = layer / 24
return value / 4, value / 2, value
end
local function sand_color(layer)
return layer / 32 + 0.2, layer / 32 + 0.15, 0.4
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 - 0.1
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 < 22 then
return sand_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 WATER = love.graphics.newQuad(1, 1, 8, 8, tex)
local SAND = love.graphics.newQuad(11, 1, 8, 8, tex)
local DIRT = love.graphics.newQuad(21, 1, 8, 8, tex)
local GRASS = love.graphics.newQuad(31, 1, 8, 8, tex)
local STONE = love.graphics.newQuad(1, 11, 8, 8, tex)
local SNOW = love.graphics.newQuad(11, 11, 8, 8, tex)
local function dirt_sprite(layer)
if layer < 32 then
return DIRT
end
return GRASS
end
local function mountain_sprite(layer)
if layer < 58 then
return STONE
end
return SNOW
end
local function pick_sprite(maxlayer)
if maxlayer < 16 then
return WATER
end
if maxlayer < 22 then
return SAND
end
if maxlayer < 46 then
return dirt_sprite
end
return mountain_sprite
end
local z = require("zprite").zchunk.new(tex, 128, 64)
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, pick_sprite(layers), 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