From b259aa3839fa6795a995ae833017f7f6911712bc Mon Sep 17 00:00:00 2001 From: PeaAshMeter Date: Sat, 27 Dec 2025 03:35:56 +0300 Subject: [PATCH] introduce basic offscreen render stack --- lib/character/behaviors/shadowcaster.lua | 0 lib/character/behaviors/sprite.lua | 33 +++++++++++++++++--- lib/level/grid/tile_grid.lua | 2 ++ lib/level/level.lua | 7 +++++ lib/level/render.lua | 39 ++++++++++++++++++++++++ lib/spellbook.lua | 2 ++ main.lua | 3 -- 7 files changed, 79 insertions(+), 7 deletions(-) create mode 100644 lib/character/behaviors/shadowcaster.lua create mode 100644 lib/level/render.lua diff --git a/lib/character/behaviors/shadowcaster.lua b/lib/character/behaviors/shadowcaster.lua new file mode 100644 index 0000000..e69de29 diff --git a/lib/character/behaviors/sprite.lua b/lib/character/behaviors/sprite.lua index 0922c4d..61d409b 100644 --- a/lib/character/behaviors/sprite.lua +++ b/lib/character/behaviors/sprite.lua @@ -38,13 +38,24 @@ function sprite:update(dt) anim:update(dt) end +local function makeGradientMesh(w, h, topColor, bottomColor) + local vertices = { + { 0, 0, 0, 0, topColor[1], topColor[2], topColor[3], topColor[4] }, -- левый верх + { w, 0, 1, 0, topColor[1], topColor[2], topColor[3], topColor[4] }, -- правый верх + { w + w * 0.1, h, 1, 1, bottomColor[1], bottomColor[2], bottomColor[3], bottomColor[4] }, -- правый низ + { 0 - w * 0.1, h, 0, 1, bottomColor[1], bottomColor[2], bottomColor[3], bottomColor[4] }, -- левый низ + } + local mesh = love.graphics.newMesh(vertices, "fan", "static") + return mesh +end + function sprite:draw() if not self.animationTable[self.state] or not Tree.assets.files.sprites.character[self.state] then return end self.owner:try(Tree.behaviors.map, function(map) local ppm = Tree.level.camera.pixelsPerMeter - local position = map.displayedPosition + local position = map.displayedPosition + Vec3 { 0.5, 0.5 } if Tree.level.selector.id == self.owner.id then local texW, texH = Tree.assets.files.sprites.character[self.state]:getWidth(), Tree.assets.files.sprites.character[self.state]:getHeight() @@ -54,11 +65,25 @@ function sprite:draw() love.graphics.setShader(shader) end - self.animationTable[self.state]:draw(Tree.assets.files.sprites.character[self.state], - position.x + 0.5, - position.y + 0.5, nil, 1 / ppm * self.side, 1 / ppm, 38, 47) + + love.graphics.setCanvas(Tree.level.render.shadowLayer) + love.graphics.setColor(0, 0, 0, 0.5) + love.graphics.ellipse("fill", position.x, position.y, 0.2, 0.2 * math.cos(math.pi / 4)) + local mesh = makeGradientMesh(0.4, 1.5, { 0, 0, 0, 0.5 }, { 0, 0, 0, 0 }) + love.graphics.push() + love.graphics.translate(position.x, position.y) + love.graphics.rotate(-3 * math.pi / 4) + love.graphics.translate(-0.2, 0) + love.graphics.draw(mesh) + love.graphics.pop() + + love.graphics.setCanvas(Tree.level.render.spriteLayer) love.graphics.setColor(1, 1, 1) + self.animationTable[self.state]:draw(Tree.assets.files.sprites.character[self.state], + position.x, + position.y, nil, 1 / ppm * self.side, 1 / ppm, 38, 47) love.graphics.setShader() + love.graphics.setCanvas() end ) end diff --git a/lib/level/grid/tile_grid.lua b/lib/level/grid/tile_grid.lua index 776b2e0..2625b5b 100644 --- a/lib/level/grid/tile_grid.lua +++ b/lib/level/grid/tile_grid.lua @@ -13,9 +13,11 @@ local function new(type, template, size) end function map:draw() + love.graphics.setCanvas(Tree.level.render.floorLayer) utils.each(self.__grid, function(el) el:draw() end) + love.graphics.setCanvas() end return { new = new } diff --git a/lib/level/level.lua b/lib/level/level.lua index 16991e9..4d79815 100644 --- a/lib/level/level.lua +++ b/lib/level/level.lua @@ -8,6 +8,7 @@ local utils = require "lib.utils.utils" --- @field camera Camera --- @field tileGrid TileGrid --- @field turnOrder TurnOrder +--- @field render Render local level = {} level.__index = level @@ -26,6 +27,7 @@ local function new(type, template) selector = (require "lib.level.selector").new(), camera = (require "lib.level.camera").new(), turnOrder = (require "lib.level.turn_order").new(), + render = (require "lib.level.render").new() }, level) end @@ -39,10 +41,15 @@ function level:update(dt) end function level:draw() + self.camera:attach() + self.render:clear() self.tileGrid:draw() while not self.characterGrid.yOrderQueue:is_empty() do -- по сути это сортировка кучей за n log n self.characterGrid.yOrderQueue:pop():draw() end + self.camera:detach() + + self.render:draw() end return { diff --git a/lib/level/render.lua b/lib/level/render.lua new file mode 100644 index 0000000..78d8299 --- /dev/null +++ b/lib/level/render.lua @@ -0,0 +1,39 @@ +--- @class Render +--- @field shadowLayer love.Canvas +--- @field spriteLayer love.Canvas +--- @field floorLayer love.Canvas +--- @field overlayLayer love.Canvas +local render = {} +render.__index = render + +function render:clear() + love.graphics.setCanvas(self.shadowLayer) + love.graphics.clear(1, 1, 1, 0) + love.graphics.setCanvas(self.spriteLayer) + love.graphics.clear() + love.graphics.setCanvas(self.floorLayer) + love.graphics.clear() + love.graphics.setCanvas(self.overlayLayer) + love.graphics.clear() +end + +function render:draw() + -- пол -> тени -> спрайты -> оверлей + love.graphics.draw(self.floorLayer) + love.graphics.setBlendMode("multiply", "premultiplied") + love.graphics.draw(self.shadowLayer) + love.graphics.setBlendMode("alpha") + love.graphics.draw(self.spriteLayer) + love.graphics.draw(self.overlayLayer) +end + +local function new() + return setmetatable({ + shadowLayer = love.graphics.newCanvas(1280, 720), + spriteLayer = love.graphics.newCanvas(1280, 720), + floorLayer = love.graphics.newCanvas(1280, 720), + overlayLayer = love.graphics.newCanvas(1280, 720), + }, render) +end + +return { new = new } diff --git a/lib/spellbook.lua b/lib/spellbook.lua index 7f22b1e..7130f25 100644 --- a/lib/spellbook.lua +++ b/lib/spellbook.lua @@ -68,10 +68,12 @@ end function walk:draw() if not self.path then return end --- Это отрисовка пути персонажа к мышке + love.graphics.setCanvas(Tree.level.render.overlayLayer) love.graphics.setColor(0.6, 0.75, 0.5) for p in self.path:values() do love.graphics.circle("fill", p.x + 0.45, p.y + 0.45, 0.1) end + love.graphics.setCanvas() love.graphics.setColor(1, 1, 1) end diff --git a/main.lua b/main.lua index bd2a7a8..e77cdba 100644 --- a/main.lua +++ b/main.lua @@ -56,11 +56,8 @@ function love.draw() love.graphics.draw(Tree.assets.files.cats, 0, 0) love.graphics.pop() - Tree.level.camera:attach() - Tree.level:draw() - Tree.level.camera:detach() testLayout:draw() love.graphics.setColor(1, 1, 1)