move shadows-related logic into its own behavior
This commit is contained in:
parent
767ddc459c
commit
03070cfff7
@ -4,3 +4,4 @@ Tree.behaviors.spellcaster = require "lib.character.behaviors.spellcaster"
|
|||||||
Tree.behaviors.sprite = require "lib.character.behaviors.sprite"
|
Tree.behaviors.sprite = require "lib.character.behaviors.sprite"
|
||||||
Tree.behaviors.stats = require "lib.character.behaviors.stats"
|
Tree.behaviors.stats = require "lib.character.behaviors.stats"
|
||||||
Tree.behaviors.residentsleeper = require "lib.character.behaviors.residentsleeper"
|
Tree.behaviors.residentsleeper = require "lib.character.behaviors.residentsleeper"
|
||||||
|
Tree.behaviors.shadowcaster = require "lib.character.behaviors.shadowcaster"
|
||||||
|
|||||||
@ -0,0 +1,98 @@
|
|||||||
|
--- @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
|
||||||
@ -38,17 +38,6 @@ function sprite:update(dt)
|
|||||||
anim:update(dt)
|
anim:update(dt)
|
||||||
end
|
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()
|
function sprite:draw()
|
||||||
if not self.animationTable[self.state] or not Tree.assets.files.sprites.character[self.state] then return end
|
if not self.animationTable[self.state] or not Tree.assets.files.sprites.character[self.state] then return end
|
||||||
|
|
||||||
@ -57,71 +46,9 @@ function sprite:draw()
|
|||||||
local ppm = Tree.level.camera.pixelsPerMeter
|
local ppm = Tree.level.camera.pixelsPerMeter
|
||||||
local position = map.displayedPosition + Vec3 { 0.5, 0.5 }
|
local position = map.displayedPosition + Vec3 { 0.5, 0.5 }
|
||||||
|
|
||||||
Tree.level.camera:detach()
|
|
||||||
love.graphics.push()
|
|
||||||
love.graphics.scale(ppm)
|
|
||||||
love.graphics.setCanvas(Tree.level.render.shadowLayer)
|
|
||||||
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))
|
|
||||||
|
|
||||||
local r = love.timer.getTime() % (2 * math.pi)
|
|
||||||
local doWeUseFakeShadow = function(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
|
|
||||||
|
|
||||||
local drawFakeShadow, opacity = doWeUseFakeShadow(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))
|
|
||||||
self.animationTable[self.state]:draw(Tree.assets.files.sprites.character[self.state],
|
|
||||||
0,
|
|
||||||
0, nil, ((nangle >= math.pi / 2 and nangle < (3 * math.pi / 2)) and -1 or 1) / ppm * self.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()
|
|
||||||
|
|
||||||
Tree.level.camera:attach()
|
|
||||||
love.graphics.setCanvas(Tree.level.render.spriteLayer)
|
love.graphics.setCanvas(Tree.level.render.spriteLayer)
|
||||||
|
Tree.level.camera:attach()
|
||||||
|
|
||||||
love.graphics.setColor(1, 1, 1)
|
love.graphics.setColor(1, 1, 1)
|
||||||
if Tree.level.selector.id == self.owner.id then
|
if Tree.level.selector.id == self.owner.id then
|
||||||
local texW, texH = Tree.assets.files.sprites.character[self.state]:getWidth(),
|
local texW, texH = Tree.assets.files.sprites.character[self.state]:getWidth(),
|
||||||
@ -134,7 +61,9 @@ function sprite:draw()
|
|||||||
self.animationTable[self.state]:draw(Tree.assets.files.sprites.character[self.state],
|
self.animationTable[self.state]:draw(Tree.assets.files.sprites.character[self.state],
|
||||||
position.x,
|
position.x,
|
||||||
position.y, nil, 1 / ppm * self.side, 1 / ppm, 38, 47)
|
position.y, nil, 1 / ppm * self.side, 1 / ppm, 38, 47)
|
||||||
|
|
||||||
love.graphics.setShader()
|
love.graphics.setShader()
|
||||||
|
Tree.level.camera:detach()
|
||||||
love.graphics.setCanvas()
|
love.graphics.setCanvas()
|
||||||
end
|
end
|
||||||
)
|
)
|
||||||
|
|||||||
@ -31,6 +31,7 @@ local function spawn(name, spriteDir, position, size, initiative)
|
|||||||
Tree.behaviors.stats.new(nil, nil, initiative),
|
Tree.behaviors.stats.new(nil, nil, initiative),
|
||||||
Tree.behaviors.map.new(position, size),
|
Tree.behaviors.map.new(position, size),
|
||||||
Tree.behaviors.sprite.new(spriteDir),
|
Tree.behaviors.sprite.new(spriteDir),
|
||||||
|
Tree.behaviors.shadowcaster.new(),
|
||||||
Tree.behaviors.spellcaster.new()
|
Tree.behaviors.spellcaster.new()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -14,9 +14,11 @@ end
|
|||||||
|
|
||||||
function map:draw()
|
function map:draw()
|
||||||
love.graphics.setCanvas(Tree.level.render.floorLayer)
|
love.graphics.setCanvas(Tree.level.render.floorLayer)
|
||||||
|
Tree.level.camera:attach()
|
||||||
utils.each(self.__grid, function(el)
|
utils.each(self.__grid, function(el)
|
||||||
el:draw()
|
el:draw()
|
||||||
end)
|
end)
|
||||||
|
Tree.level.camera:detach()
|
||||||
love.graphics.setCanvas()
|
love.graphics.setCanvas()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@ -41,15 +41,11 @@ function level:update(dt)
|
|||||||
end
|
end
|
||||||
|
|
||||||
function level:draw()
|
function level:draw()
|
||||||
self.camera:attach()
|
|
||||||
self.render:clear()
|
self.render:clear()
|
||||||
self.tileGrid:draw()
|
self.tileGrid:draw()
|
||||||
while not self.characterGrid.yOrderQueue:is_empty() do -- по сути это сортировка кучей за n log n
|
while not self.characterGrid.yOrderQueue:is_empty() do -- по сути это сортировка кучей за n log n
|
||||||
self.characterGrid.yOrderQueue:pop():draw()
|
self.characterGrid.yOrderQueue:pop():draw()
|
||||||
end
|
end
|
||||||
self.camera:detach()
|
|
||||||
--self.render.shadowLayer:newImageData():encode("png", "shadowLayer.png")
|
|
||||||
-- os.exit(0)
|
|
||||||
|
|
||||||
self.render:draw()
|
self.render:draw()
|
||||||
end
|
end
|
||||||
|
|||||||
@ -68,12 +68,14 @@ end
|
|||||||
function walk:draw()
|
function walk:draw()
|
||||||
if not self.path then return end
|
if not self.path then return end
|
||||||
--- Это отрисовка пути персонажа к мышке
|
--- Это отрисовка пути персонажа к мышке
|
||||||
|
Tree.level.camera:attach()
|
||||||
love.graphics.setCanvas(Tree.level.render.overlayLayer)
|
love.graphics.setCanvas(Tree.level.render.overlayLayer)
|
||||||
love.graphics.setColor(0.6, 0.75, 0.5)
|
love.graphics.setColor(0.6, 0.75, 0.5)
|
||||||
for p in self.path:values() do
|
for p in self.path:values() do
|
||||||
love.graphics.circle("fill", p.x + 0.45, p.y + 0.45, 0.1)
|
love.graphics.circle("fill", p.x + 0.45, p.y + 0.45, 0.1)
|
||||||
end
|
end
|
||||||
love.graphics.setCanvas()
|
love.graphics.setCanvas()
|
||||||
|
Tree.level.camera:detach()
|
||||||
love.graphics.setColor(1, 1, 1)
|
love.graphics.setColor(1, 1, 1)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user