consolidate single color sprites into one master file

This commit is contained in:
Your Name 2026-08-22 11:44:51 -04:00
parent 7d84f595e4
commit fe5a11112f
16 changed files with 90 additions and 53 deletions

View file

@ -3,6 +3,20 @@ require "libs/TSerial"
local targetFolder = "art"
local reanalyzeCells = true
-- Sprites loaded directly by dedicated entity classes or used as reference art
-- (the palette swatch), not placeable RGB assets. Every other master PNG in a
-- content folder is a colour asset. Keeping this list preserves the exact
-- palette set from when assets were identified by their _r/_g/_b channel files.
local NON_ASSET_SPRITES = {
palette = true,
color_changing_wall = true,
door_locked_w = true,
door_unlocked = true,
player_sad = true,
player_w = true,
switch_pressed = true,
}
function getAllAssets()
local objectnames = {}
local topFolder = "art"
@ -12,44 +26,46 @@ function getAllAssets()
-- we ignore directories which are prepended w/ an underscore
if not string.find(folder, "%.") then
objectnames[folder] = {}
-- love.filesystem.createDirectory("art/" .. folder)
-- this is a folder, probably
local newFiles = love.filesystem.getDirectoryItems(topFolder .. "/" .. folder)
for _, fileToAnalyze in pairs(newFiles) do
if fileToAnalyze:find("_r.png") or fileToAnalyze:find("_g.png") or fileToAnalyze:find("_b.png")then
local color
if fileToAnalyze:find("_r.png") then color = "red"
elseif fileToAnalyze:find("_g.png") then color = "green"
elseif fileToAnalyze:find("_b.png") then color = "blue" end
-- One full-colour master PNG per asset. The draw path tints it
-- per gun (see Entity:draw), so red/green/blue copies are just
-- the same master drawn through gColor[channel]; the channels are
-- split at load time, not stored as separate files.
if fileToAnalyze:find("%.png$") then
local name = fileToAnalyze:sub(1, fileToAnalyze:len() - 4)
local name = fileToAnalyze:sub(1, fileToAnalyze:len() - 6)
-- first folder to define a name wins; skip engine/reference art
if not NON_ASSET_SPRITES[name]
and not (globalAssetProperties[name] and globalAssetProperties[name].directory ~= folder) then
if not globalAssetProperties[name] then
globalAssetProperties[name] = {}
local sprite = topFolder .. "/" .. folder .. "/" .. fileToAnalyze
if not globalAssetProperties[name] then
globalAssetProperties[name] = {}
globalAssetProperties[name].preload = false
end
globalAssetProperties[name].directory = folder
globalAssetProperties[name].sprites = {}
globalAssetProperties[name].preload = false
end
-- all three channels point at the same master image
globalAssetProperties[name].sprites = { red = sprite, green = sprite, blue = sprite }
-- class comes from a <name>.meta sitting next to the art
-- (authoritative); default to immoveable if none exists
local metaPath = topFolder .. "/" .. folder .. "/" .. name .. ".meta"
if love.filesystem.getInfo(metaPath, "file") then
globalAssetProperties[name].class = TSerial.unpack(love.filesystem.read(metaPath)).class
elseif not globalAssetProperties[name].class then
globalAssetProperties[name].class = "immoveable"
end
-- class comes from a <name>.meta sitting next to the art
-- (authoritative); default to immoveable if none exists
local metaPath = topFolder .. "/" .. folder .. "/" .. name .. ".meta"
if love.filesystem.getInfo(metaPath, "file") then
globalAssetProperties[name].class = TSerial.unpack(love.filesystem.read(metaPath)).class
elseif not globalAssetProperties[name].class then
globalAssetProperties[name].class = "immoveable"
end
local sprite = topFolder .. "/" .. folder .. "/" .. fileToAnalyze
globalAssetProperties[name].sprites[color] = sprite
-- Precompute the occupied-cell shape once per asset/colour and
-- cache it here; entities share this table by reference so
-- collision never rescans pixels at runtime. Keyed per colour
-- (each channel leaves its own gaps) rather than reset per file.
globalAssetProperties[name].cells = globalAssetProperties[name].cells or {}
if not globalAssetProperties[name].cells[color] or reanalyzeCells then
globalAssetProperties[name].cells[color] = getCellsFromSprite(sprite)
-- Precompute per-channel occupied-cell shapes once and cache
-- here; entities share this table by reference so collision
-- never rescans pixels at runtime. Keyed per colour because
-- each channel of the master leaves its own gaps.
if reanalyzeCells or not globalAssetProperties[name].cells then
globalAssetProperties[name].cells = getChannelCells(sprite)
end
end
end
end