fix renderer

This commit is contained in:
Your Name 2026-08-07 00:40:45 -04:00
parent 3ceb07f4d1
commit 886679816b
3 changed files with 42 additions and 56 deletions

View file

@ -8,7 +8,11 @@ function Door:initialize(x, y)
y = y,
color = "white",
collision = "unmoveable",
sprite = sprites.door["green"] --doesn't matter for now which we put here b/c, we override the draw function neway
sprites = {
red = sprites.door.red,
green = sprites.door.green,
blue = sprites.door.blue,
},
})
self.locked = true
@ -16,25 +20,18 @@ function Door:initialize(x, y)
for _, color in pairs({"red", "green", "blue"}) do
self.colors[color] = true --these are currently loc_ed
end
self:refreshSprites()
end
function Door:draw()
if self.locked then
for color, active in pairs(self.colors) do
if active then
love.graphics.setColor(gColor[color]:set())
local p = self:getDrawPos()
love.graphics.draw(sprites.door[color], p.x + self.drawOffset.x, p.y + self.drawOffset.y, 0, drawScale, drawScale)
end
end
love.graphics.setColor(gColor.white:set())
local p = self:getDrawPos()
love.graphics.draw(sprites.door["white"], p.x + self.drawOffset.x, p.y + self.drawOffset.y, 0, drawScale, drawScale)
else
for color, active in pairs(self.colors) do
love.graphics.setColor(gColor[color]:set())
local p = self:getDrawPos()
love.graphics.draw(sprites.door["unlocked"], p.x + self.drawOffset.x, p.y + self.drawOffset.y, 0, drawScale, drawScale)
-- keep the per-channel sprite map in sync with lock state so the shared
-- Entity:draw(channel) renders the door with no door-specific draw code
function Door:refreshSprites()
self.sprites = {}
for _, c in ipairs({"red", "green", "blue"}) do
if self.locked then
if self.colors[c] then self.sprites[c] = sprites.door[c] end
else
self.sprites[c] = sprites.door.unlocked
end
end
end
@ -56,6 +53,8 @@ function Door:setColors(colors)
else
if not self.locked then self:lock() end
end
self:refreshSprites()
end
function Door:unlock()

View file

@ -2,13 +2,19 @@ Entity = class("Entity")
function Entity:initialize(t)
self.x, self.y = t.x, t.y
self.spriteSize = {w = t.sprite:getWidth(), h = t.sprite:getHeight()}
-- sprites keyed by channel ("red"/"green"/"blue"). Single-color entities pass
-- t.sprite + t.color and get one entry; multi-channel ones (doors) pass
-- t.sprites directly. The renderer draws only the channels the player has, so
-- no entity decides its own visibility (see Room:draw).
self.sprites = t.sprites or { [t.color] = t.sprite }
local repSprite = t.sprite or (t.sprites and select(2, next(t.sprites)))
self.spriteSize = {w = repSprite:getWidth(), h = repSprite:getHeight()}
self.size = {w = self.spriteSize.w / 16, h = self.spriteSize.h / 16}
self.cellShape = t.cellShape or self:cellShapeFromBox(self.size)
self.name = t.name
self.color = Color:new(t.color)
self.collision = t.collision --"none", "moveable", "unmoveable"
self.sprite = t.sprite
self.sprite = repSprite
self.shaAmount = t.sha or 1
self.onBump = t.onBump or function(self) return true end
self.tick = t.tick or function(self) return true end
@ -108,10 +114,12 @@ function Entity:tick()
return self.tick()
end
function Entity:draw()
love.graphics.setColor(self.color:set())
function Entity:draw(channel)
local sprite = self.sprites[channel]
if not sprite then return end
love.graphics.setColor(gColor[channel]:set())
local p = self:getDrawPos()
love.graphics.draw(self.sprite, p.x + self.drawOffset.x, p.y + self.drawOffset.y, 0, drawScale, drawScale)
love.graphics.draw(sprite, p.x + self.drawOffset.x, p.y + self.drawOffset.y, 0, drawScale, drawScale)
end
function Entity:canMove()

View file

@ -124,41 +124,20 @@ end
function Room:draw()
-- you only perceive the color channels the player actually has: with only a
-- red copy, only the red layer is drawn (a stacked r+g+b wall shows as red,
-- not white). Doors span all channels, so dedupe and draw them once.
local visible = {}
for _, c in ipairs(self.colorsPlayerHas) do visible[c] = true end
-- draw only the channels the player has. Each object just exposes sprites per
-- channel via Entity:draw(channel); a door registered on all three channels
-- naturally draws its red sprite on the red pass, etc. No per-object logic.
local has = {}
for _, channel in ipairs(self.colorsPlayerHas) do
has[channel] = true
if self.player[channel] then self.player[channel]:draw(channel) end
for _, entity in pairs(self.collideables[channel]) do entity:draw(channel) end
for _, switch in pairs(self.switches[channel]) do switch:draw(channel) end
end
for color, player in pairs(self.player) do
if visible[color] then player:draw() end
end
local drawnDoors = {}
for color, entityArray in pairs(self.collideables) do
if visible[color] then
for _, entity in pairs(entityArray) do
if entity:isInstanceOf(Door) then
if not drawnDoors[entity] then
drawnDoors[entity] = true
entity:draw()
end
else
entity:draw()
end
end
end
end
for color, switchArray in pairs(self.switches) do
if visible[color] then
for _, switch in pairs(switchArray) do
switch:draw()
end
end
end
-- npcs (old "sages") are just markers for now: draw a "?" in their cell,
-- tinted to only the channels the player has (never a white pixel)
-- npcs (old "sages") are markers for now: a "?" tinted to the player's channels
local cellW, cellH = width / gridWidth, height / gridHeight
love.graphics.setColor(visible.red and 255 or 0, visible.green and 255 or 0, visible.blue and 255 or 0)
love.graphics.setColor(has.red and 255 or 0, has.green and 255 or 0, has.blue and 255 or 0)
for _, npc in ipairs(self.npcs) do
love.graphics.print("?", (npc.x - 1) * cellW + cellW * 0.3, (npc.y - 1) * cellH + cellH * 0.1, 0, 2, 2)
end