--- @class ShadowcasterBehavior : Behavior local behavior = {} behavior.id = "shadowcaster" behavior.__index = behavior function behavior.new() return setmetatable({}, behavior) 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 local function getFakeShadow(r) local pi = math.pi if r <= pi / 4 then -- 1 return false, 1 end if r <= pi / 2 then -- 2 return true, 1 - (r - pi / 4) / (pi / 4) end if r <= 3 * pi / 4 then -- 3 return true, (r - pi / 2) / (pi / 4) end if r <= 5 * pi / 4 then -- 4 return false, 1 end if r <= 3 * pi / 2 then -- 5 return true, 1 - (r - 5 * pi / 4) / (pi / 4) end if r <= 7 * pi / 4 then -- 6 return true, (r - 3 * pi / 2) / (pi / 4) end -- 1 return false, 1 end function behavior:draw() local sprite = self.owner:has(Tree.behaviors.sprite) local map = self.owner:has(Tree.behaviors.map) if not map then return end local ppm = Tree.level.camera.pixelsPerMeter local position = map.displayedPosition + Vec3 { 0.5, 0.5 } love.graphics.setCanvas(Tree.level.render.shadowLayer) love.graphics.push() love.graphics.scale(ppm) love.graphics.setColor(0, 0, 0, 0.5) love.graphics.translate(position.x, position.y) love.graphics.ellipse("fill", 0, 0, 0.2, 0.2 * math.cos(math.pi / 4)) if not sprite then love.graphics.pop() return end local r = love.timer.getTime() % (2 * math.pi) local drawFakeShadow, opacity = getFakeShadow(r) local nangle = (math.pi + r) % (2 * math.pi) love.graphics.rotate(nangle) love.graphics.setColor(0, 0, 0, math.min(opacity * opacity, 0.5)) sprite.animationTable[sprite.state]:draw(Tree.assets.files.sprites.character[sprite.state], 0, 0, nil, ((nangle >= math.pi / 2 and nangle < (3 * math.pi / 2)) and -1 or 1) / ppm * sprite.side, 1.2 / ppm, 38, 47) if drawFakeShadow then love.graphics.setColor(0, 0, 0, 1) local mesh = makeGradientMesh(0.4, 1, { 0, 0, 0, 0.15 }, { 0, 0, 0, 0.0 }) love.graphics.push() love.graphics.rotate(math.pi) love.graphics.translate(-0.2, 0) love.graphics.draw(mesh) love.graphics.pop() end love.graphics.pop() love.graphics.setColor(1, 1, 1) love.graphics.setCanvas() end return behavior