186 lines
4.0 KiB
Lua
186 lines
4.0 KiB
Lua
-- based on
|
|
-- https://healeycodes.com/virtual-ants
|
|
-- https://github.com/healeYcodes/virtual-ants/blob/main/index.html
|
|
|
|
require("util")
|
|
|
|
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(#rules)
|
|
COLORS = {}
|
|
for i, color in pairs(scheme) do
|
|
COLORS[i] = {
|
|
clockwise = rules:sub(i, i) == "r",
|
|
rgba = color
|
|
}
|
|
end
|
|
end
|
|
|
|
local function initScreen()
|
|
local width, height = love.graphics.getDimensions()
|
|
WIDTH, HEIGHT = round2even(width), round2even(height)
|
|
CANVAS = love.graphics.newCanvas(WIDTH, HEIGHT)
|
|
CANVAS:renderTo(function()
|
|
local c = COLORS[1].rgba
|
|
love.graphics.setColor({ c[1], c[2], c[3], 0.9 })
|
|
love.graphics.rectangle("fill", 0, 0, WIDTH, HEIGHT)
|
|
end)
|
|
end
|
|
|
|
local function initFont()
|
|
FONT = love.graphics.newFont(16)
|
|
love.graphics.setFont(FONT)
|
|
FPS_WIDTH = FONT:getWidth("120 FPS")
|
|
FPS_HEIGHT = FONT:getHeight()
|
|
end
|
|
|
|
local function spawnAnt(x, y)
|
|
table.insert(ANTS, {
|
|
x = x,
|
|
y = y,
|
|
direction = "u"
|
|
})
|
|
end
|
|
|
|
local function spawnAntCentered()
|
|
spawnAnt(
|
|
(WIDTH / 2) - ((WIDTH / 2) % UNITS),
|
|
(HEIGHT / 2) - ((HEIGHT / 2) % UNITS)
|
|
)
|
|
end
|
|
|
|
local function initAnts()
|
|
ANTS = {}
|
|
spawnAntCentered()
|
|
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 rules = args[1] or "RL"
|
|
UNITS = args[2] or 4
|
|
STEPS_PER_FRAME = args[3] or 5
|
|
initColors(rules)
|
|
initScreen()
|
|
initFont()
|
|
initAnts()
|
|
initGrid()
|
|
end
|
|
|
|
local function antColor(ant)
|
|
return GRID[ant.x][ant.y]
|
|
end
|
|
|
|
local function setColor(ant, color)
|
|
GRID[ant.x][ant.y] = color
|
|
end
|
|
|
|
local function updateColor(ant)
|
|
local val = antColor(ant)
|
|
if val == #COLORS then
|
|
val = 1
|
|
else
|
|
val = val + 1
|
|
end
|
|
setColor(ant, val)
|
|
end
|
|
|
|
local function nextColor(ant)
|
|
local c = COLORS[antColor(ant)]
|
|
updateColor(ant)
|
|
return c
|
|
end
|
|
|
|
function love.mousepressed(x, y)
|
|
spawnAnt(x, y)
|
|
end
|
|
|
|
function love.update()
|
|
pcall(function()
|
|
require("lurker").update()
|
|
end)
|
|
for _ = 1, STEPS_PER_FRAME do
|
|
for i, ant in pairs(ANTS) do
|
|
local c = nextColor(ant)
|
|
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
|
|
ANTS[i] = ant
|
|
end
|
|
end
|
|
end
|
|
|
|
local function paintFPS()
|
|
love.graphics.setBlendMode("alpha")
|
|
local fps = tostring(love.timer.getFPS()) .. " FPS"
|
|
love.graphics.setColor(COLORS[1].rgba)
|
|
love.graphics.rectangle("fill", WIDTH - FPS_WIDTH - 10, HEIGHT - FPS_HEIGHT - 20, FPS_WIDTH + 30, FPS_HEIGHT + 10, 5, 5)
|
|
love.graphics.setColor(COLORS[#COLORS].rgba)
|
|
love.graphics.print(fps, WIDTH - FPS_WIDTH - 5, HEIGHT - FPS_HEIGHT - 15)
|
|
end
|
|
|
|
function love.draw()
|
|
love.graphics.setBlendMode("alpha", "premultiplied")
|
|
love.graphics.setColor(COLORS[1].rgba)
|
|
love.graphics.draw(CANVAS, 0, 0)
|
|
paintFPS()
|
|
end
|