local easing = require "lib.utils.easing" --- @class ShadowcasterBehavior : Behavior local behavior = {} behavior.id = "shadowcaster" behavior.__index = behavior function behavior.new() return setmetatable({}, behavior) end function behavior:draw() local sprite = self.owner:has(Tree.behaviors.sprite) local positioned = self.owner:has(Tree.behaviors.positioned) if not positioned then return end if not sprite then return end local ppm = Tree.level.camera.pixelsPerMeter local position = positioned.position + Vec3 { 0.5, 0.5 } local lightIds = Tree.level.lightGrid:query(position, 5) --- @type Character[] local lights = {} for _, id in ipairs(lightIds) do table.insert(lights, Tree.level.characters[id]) end -- 1. Эллипс тени Tree.level.render:enqueue(Tree.level.render.LAYERS.SHADOW, position.y, function() love.graphics.push() love.graphics.setColor(0, 0, 0, 1) love.graphics.translate(position.x, position.y) love.graphics.ellipse("fill", 0, 0, sprite.manifest.size / 2, sprite.manifest.size / 2 * math.cos(math.pi / 4)) love.graphics.pop() end) -- 2. Свет на спрайте if #lights > 0 then Tree.level.render:enqueue(Tree.level.render.LAYERS.SPRITE_LIGHT, position.y, function() love.graphics.setBlendMode("add") for _, light in ipairs(lights) do local lightPos = light:has(Tree.behaviors.positioned).position local lightVec = lightPos - position local lightColor = light:has(Tree.behaviors.light).color if lightPos.y > position.y then love.graphics.setColor(lightColor.x, lightColor.y, lightColor.z, 1 - 0.3 * lightVec:length()) elseif position.y - lightPos.y < 3 then love.graphics.setColor(lightColor.x, lightColor.y, lightColor.z, (1 - easing.easeInSine((position.y - lightPos.y))) - 0.3 * lightVec:length()) end sprite.animationTable[sprite.state]:draw(sprite.sheets[sprite.state], position.x, position.y, nil, 1 / ppm * sprite.side, 1 / ppm, sprite.manifest.base.x, sprite.manifest.base.y) end love.graphics.setBlendMode("alpha") love.graphics.setColor(1, 1, 1) end) end end return behavior