155 lines
3.2 KiB
Lua
155 lines
3.2 KiB
Lua
|
-- based on
|
||
|
-- https://github.com/healeYcodes/virtual-ants/blob/main/index.html
|
||
|
|
||
|
require("util")
|
||
|
|
||
|
local function round2even(num)
|
||
|
return 2 * math.floor(num / 2)
|
||
|
end
|
||
|
|
||
|
local function rotate(direction, clockwise)
|
||
|
local match
|
||
|
if clockwise then
|
||
|
match = {
|
||
|
u = "r",
|
||
|
r = "d",
|
||
|
d = "l",
|
||
|
l = "u",
|
||
|
}
|
||
|
else
|
||
|
match = {
|
||
|
u = "l",
|
||
|
l = "d",
|
||
|
d = "r",
|
||
|
r = "u"
|
||
|
}
|
||
|
end
|
||
|
return match[direction]
|
||
|
end
|
||
|
|
||
|
local function initColors(rules)
|
||
|
rules = rules:lower()
|
||
|
local colorbrewer = require("colorbrewer")
|
||
|
local scheme = colorbrewer.random()
|
||
|
local variant = scheme[#rules]
|
||
|
COLORS = {}
|
||
|
for i = 1, #rules do
|
||
|
COLORS[i] = {
|
||
|
clockwise = rules:sub(i, i) == "r",
|
||
|
rgba = variant[i]
|
||
|
}
|
||
|
end
|
||
|
end
|
||
|
|
||
|
local function initScreen(width, height)
|
||
|
love.window.setMode(width, height, { highdpi = true })
|
||
|
WIDTH, HEIGHT = round2even(width), round2even(height)
|
||
|
CANVAS = love.graphics.newCanvas(WIDTH, HEIGHT)
|
||
|
CANVAS:renderTo(function()
|
||
|
local color = COLORS[1].rgba
|
||
|
color[4] = 0.9
|
||
|
love.graphics.setColor(color)
|
||
|
love.graphics.rectangle("fill", 0, 0, WIDTH, HEIGHT)
|
||
|
end)
|
||
|
UNITS = 8
|
||
|
end
|
||
|
|
||
|
local function initAnt()
|
||
|
ANT = {
|
||
|
x = (WIDTH / 2) - ((WIDTH / 2) % UNITS),
|
||
|
y = (HEIGHT / 2) - ((HEIGHT / 2) % UNITS),
|
||
|
direction = "u",
|
||
|
}
|
||
|
end
|
||
|
|
||
|
local function initGrid()
|
||
|
GRID = {}
|
||
|
GRID.mt = {}
|
||
|
setmetatable(GRID, GRID.mt)
|
||
|
GRID.mt.__index = function(table, key)
|
||
|
table[key] = {}
|
||
|
table[key].mt = {}
|
||
|
setmetatable(table[key], table[key].mt)
|
||
|
table[key].mt.__index = function(innerTable, innerKey)
|
||
|
innerTable[innerKey] = 1
|
||
|
return innerTable[innerKey]
|
||
|
end
|
||
|
return table[key]
|
||
|
end
|
||
|
end
|
||
|
|
||
|
function love.load(args)
|
||
|
local width = args[1] or 800
|
||
|
local height = args[2] or 600
|
||
|
local rules = args[3] or "RL"
|
||
|
initColors(rules)
|
||
|
initScreen(width, height)
|
||
|
initAnt()
|
||
|
initGrid()
|
||
|
end
|
||
|
|
||
|
local function color(x, y)
|
||
|
return GRID[x][y]
|
||
|
end
|
||
|
|
||
|
local function current()
|
||
|
return color(ANT.x, ANT.y)
|
||
|
end
|
||
|
|
||
|
local function setCurrent(index)
|
||
|
GRID[ANT.x][ANT.y] = index
|
||
|
end
|
||
|
|
||
|
local function updateCurrent()
|
||
|
local val = current()
|
||
|
if val == #COLORS then
|
||
|
val = 1
|
||
|
else
|
||
|
val = val + 1
|
||
|
end
|
||
|
setCurrent(val)
|
||
|
end
|
||
|
|
||
|
local function nextColor()
|
||
|
local c = COLORS[current()]
|
||
|
updateCurrent()
|
||
|
return c
|
||
|
end
|
||
|
|
||
|
function love.update()
|
||
|
require("lurker").update()
|
||
|
local c = nextColor()
|
||
|
ANT.direction = rotate(ANT.direction, c.clockwise)
|
||
|
CANVAS:renderTo(function()
|
||
|
love.graphics.setBlendMode("alpha")
|
||
|
love.graphics.setColor(c.rgba)
|
||
|
love.graphics.rectangle("fill", ANT.x, ANT.y, UNITS, UNITS)
|
||
|
end)
|
||
|
if ANT.direction == "u" then
|
||
|
ANT.y = ANT.y - UNITS
|
||
|
elseif ANT.direction == "r" then
|
||
|
ANT.x = ANT.x + UNITS
|
||
|
elseif ANT.direction == "d" then
|
||
|
ANT.y = ANT.y + UNITS
|
||
|
else
|
||
|
ANT.x = ANT.x - UNITS
|
||
|
end
|
||
|
|
||
|
if ANT.x >= WIDTH then
|
||
|
ANT.x = 0
|
||
|
elseif ANT.x < 0 then
|
||
|
ANT.x = (WIDTH - 1) - ((WIDTH - 1) % UNITS)
|
||
|
end
|
||
|
if ANT.y >= HEIGHT then
|
||
|
ANT.y = 0
|
||
|
elseif ANT.y < 0 then
|
||
|
ANT.y = (HEIGHT - 1) - ((HEIGHT - 1) % UNITS)
|
||
|
end
|
||
|
end
|
||
|
|
||
|
function love.draw()
|
||
|
love.graphics.setBlendMode("screen", "premultiplied")
|
||
|
love.graphics.setColor(COLORS[1].rgba)
|
||
|
love.graphics.draw(CANVAS, 0, 0)
|
||
|
end
|