src/core: add Assets module from Imperium Porcorum

This commit is contained in:
Kazhnuz 2019-01-28 09:58:12 +01:00
parent fd566ab26a
commit a14d31f527
7 changed files with 614 additions and 0 deletions

View file

@ -0,0 +1,63 @@
local Animator = Object:extend()
function Animator:new(sprite)
self.sprite = sprite
self.frame = 1
self.frameTimer = 0
self.currentAnimation = ""
self.animationData = {}
self.customSpeed = 0
self:changeToDefaultAnimation()
end
function Animator:setCustomSpeed(customSpeed)
self.customSpeed = customSpeed or 0
end
function Animator:update(dt)
if (self.currentAnimation == "") then
print("warning: no current animation data")
return 0
end
local speed = self.animationData.speed
if (self.animationData.speed) == -1 then
speed = self.customSpeed --math.abs(self.xsp / 16)
end
self.frameTimer = self.frameTimer + (speed * dt)
if self.frameTimer > 1 then
self.frameTimer = 0
if self.frame == self.animationData.endAt then
self.frame = self.animationData.loop
else
self.frame = self.frame + 1
end
end
end
function Animator:getFrame()
return self.frame
end
function Animator:draw(x, y, r, sx, sy, ox, oy, kx, ky)
self.sprite:drawFrame(self.frame, x, y, r, sx, sy, ox, oy, kx, ky)
end
function Animator:changeAnimation(name, restart)
self.currentAnimation = name
self.animationData = self.sprite.data.animations[self.currentAnimation]
local restart = restart or true
if (restart) then
self.frame = self.animationData.startAt
self.frameTimer = 0
end
end
function Animator:changeToDefaultAnimation(restart)
self:changeAnimation(self.sprite.data.metadata.defaultAnim, restart)
end
return Animator

View file

@ -0,0 +1,85 @@
local Tileset = require "core.modules.assets.tileset"
local Autotile = Object:extend()
function Autotile:new(filepath)
self.tileset = Tileset(filepath)
self.data = require(filepath .. ".lua")
self.metadata = self.data.metadata
self.tilesize = self.metadata.width
end
function Autotile:drawtile(i, j, x, y, r, sx, sy, ox, oy, kx, ky)
local i = i or 1
local j = j or 1
local tilesize = self.tilesize / 2
i = (i - 1) * 2 + 1
j = (j - 1) * 2 + 1
self.tileset:drawTile_Grid(i , j , x , y , r, sx, sy, ox, oy, kx, ky)
self.tileset:drawTile_Grid(i + 1, j , x + tilesize, y , r, sx, sy, ox, oy, kx, ky)
self.tileset:drawTile_Grid(i , j + 1, x , y + tilesize, r, sx, sy, ox, oy, kx, ky)
self.tileset:drawTile_Grid(i + 1, j + 1, x + tilesize, y + tilesize, r, sx, sy, ox, oy, kx, ky)
end
function Autotile:draw(x, y, w, h)
local w = w or self.tilesize
local h = h or self.tilesize
w = math.max(math.floor(w / self.tilesize), 1)
h = math.max(math.floor(h / self.tilesize), 1)
local halfsize = self.tilesize / 2
local tilesize = self.tilesize
if (w == 1) then
self.tileset:drawtile_Grid(1, 1, x , y)
self.tileset:drawtile_Grid(1, 6, x , y + (h*2 - 1) * halfsize)
self.tileset:drawtile_Grid(6, 1, x + (w*2 - 1) * halfsize, y)
self.tileset:drawtile_Grid(6, 6, x + (w*2 - 1) * halfsize, y + (h*2 - 1) * halfsize)
if (h > 1) then
h = h - 1
for i = 1, h do
self.tileset:drawtile_Grid(1, 3, x, y + (i * tilesize) - halfsize)
self.tileset:drawtile_Grid(6, 3, x + halfsize, y + (i * tilesize) - halfsize)
self.tileset:drawtile_Grid(1, 4, x , y + (i * tilesize))
self.tileset:drawtile_Grid(6, 4, x + halfsize, y + (i * tilesize))
end
end
-- draw just one stuff
else
if (h == 1) then
self.tileset:drawtile_Grid(1, 1, x , y)
self.tileset:drawtile_Grid(1, 6, x , y + (h*2 - 1) * halfsize)
self.tileset:drawtile_Grid(6, 1, x + (w*2 - 1) * halfsize, y)
self.tileset:drawtile_Grid(6, 6, x + (w*2 - 1) * halfsize, y + (h*2 - 1) * halfsize)
w = w - 1
for i = 1, w do
self.tileset:drawtile_Grid(3, 1, x + (i * tilesize) - halfsize, y)
self.tileset:drawtile_Grid(3, 6, x + (i * tilesize) - halfsize, y + halfsize)
self.tileset:drawtile_Grid(4, 1, x + (i * tilesize) , y )
self.tileset:drawtile_Grid(4, 6, x + (i * tilesize), y +halfsize)
end
else
self:drawtile(1, 1, x , y)
self:drawtile(1, 3, x , y + (h - 1) * tilesize)
self:drawtile(3, 1, x + (w - 1) * tilesize, y)
self:drawtile(3, 3, x + (w - 1) * tilesize, y + (h - 1) * tilesize)
w = w - 2
h = h - 2
for i=1, w do
self:drawtile(2, 1, i * tilesize, y)
self:drawtile(2, 3, i * tilesize, y + (h + 1) * tilesize)
for j=1, h do
self:drawtile(2, 2, i * tilesize, j * tilesize)
end
end
for i=1, h do
self:drawtile(1, 2, x , i * tilesize)
self:drawtile(3, 2, x + (w + 1) * tilesize, i * tilesize)
end
end
end
end
return Autotile

View file

@ -0,0 +1,26 @@
local Background = Object:extend()
function Background:new(filepath)
self.image = love.graphics.newImage(filepath)
self.batch = love.graphics.newSpriteBatch(self.image , 1000 )
self.width, self.height = self.image:getDimensions()
local w = math.floor(424 / self.width) * self.width + 1
local h = math.floor(240 / self.height) * self.height + 1
for i=-1, w do
for j=-1, h do
self.batch:add(i * self.width, j * self.height)
j = j + 1
end
i = i + 1
end
end
function Background:draw(ox, oy)
love.graphics.setColor(1, 1, 1)
love.graphics.draw(self.batch, ox, oy)
end
return Background

View file

@ -0,0 +1,153 @@
local Font = Object:extend()
-- Initilizing and configuring option
function Font:new(filename, size)
local filename = filename
self.font = love.graphics.newFont(filename, size)
self.filter = ""
self:setColor(1, 1, 1, 1)
self:setSpacing(false, 0)
self.align = "left"
end
function Font:set()
love.graphics.setFont(self.font)
end
function Font:setColor(r, g, b, a)
self.color = {}
self.color.r = r
self.color.g = g
self.color.b = b
self.color.a = a
end
function Font:setColorFromTable(color)
self.color = color
end
function Font:setSpacing(use_custom, size)
self.spacing = {}
self.spacing.active = use_custom
self.spacing.size = size
end
function Font:setAlign(align)
self.align = align
end
function Font:setFilter(filter)
self.filter = filter
end
function Font:setLineHeight(height)
self.font:setLineHeight(height)
end
-- get information functions
function Font:getHeight()
local font = self.font
return font:getHeight()
end
function Font:getWidth(string)
local spacing = 0
if (self.spacing.active == true) then
local charNumber = string.len(string)
spacing = self.spacing.size * charNumber
end
local width = self.font:getWidth(string) + spacing
return width
end
function Font:getColor()
return self.color
end
-- print functions
function Font:draw(text, x, y, limit, align, r, sx, sy, ox, oy, kx, ky)
-- draw text with color and effect applied
local limit = limit or 0
local align = align or self.align
self:applyFilter(text, x, y, limit, align, r, sx, sy, ox, oy, kx, ky)
love.graphics.setColor(self.color.r, self.color.g, self.color.b, self.color.a)
self:printf(text, x, y, limit, align, r, sx, sy, ox, oy, kx, ky)
end
function Font:print(text, x, y, align, r, sx, sy, ox, oy, kx, ky)
self:set()
if (self.spacing.active) then
utils.draw.printWithSpacing(text, self.spacing.size, align, x, y, r, sx, sy, ox, oy, kx, ky)
else
utils.draw.print(text, align, x, y, r, sx, sy, ox, oy, kx, ky)
end
end
function Font:printf(text, x, y, limit, align, r, sx, sy, ox, oy, kx, ky)
self:set()
if (limit > 0) then
love.graphics.printf(text, x, y, limit, align, r, sx, sy, ox, oy, kx, ky)
else
self:print(text, x, y, align, r, sx, sy, ox, oy, kx, ky)
end
end
-- FILTER SYSTEM
function Font:applyFilter(text, x, y, limit, align, r, sx, sy, ox, oy, kx, ky)
if self.filter == "shadow" then
self:applyFilterShadow(text, x, y, limit, align, r, sx, sy, ox, oy, kx, ky)
elseif self.filter == "border" then
self:applyFilterBorder(text, x, y, limit, align, r, sx, sy, ox, oy, kx, ky)
elseif self.filter == "doubleborder" then
self:applyFilterDoubleBorder(text, x, y, limit, align, r, sx, sy, ox, oy, kx, ky)
end
end
function Font:applyFilterShadow(text, x, y, limit, align, r, sx, sy, ox, oy, kx, ky)
love.graphics.setColor(0, 0, 0, 1)
self:printf(text, x+1, y+1, limit, align, align, r, sx, sy, ox, oy, kx, ky)
utils.draw.resetColor()
end
function Font:applyFilterBorder(text, x, y, limit, align, r, sx, sy, ox, oy, kx, ky)
love.graphics.setColor(0, 0, 0, 1)
self:printf(text, x-1, y-1, limit, align, r, sx, sy, ox, oy, kx, ky)
self:printf(text, x , y-1, limit, align, r, sx, sy, ox, oy, kx, ky)
self:printf(text, x+1, y-1, limit, align, r, sx, sy, ox, oy, kx, ky)
self:printf(text, x+1, y , limit, align, r, sx, sy, ox, oy, kx, ky)
self:printf(text, x-1, y , limit, align, r, sx, sy, ox, oy, kx, ky)
self:printf(text, x-1, y+1, limit, align, r, sx, sy, ox, oy, kx, ky)
self:printf(text, x , y+1, limit, align, r, sx, sy, ox, oy, kx, ky)
self:printf(text, x+1, y+1, limit, align, r, sx, sy, ox, oy, kx, ky)
utils.draw.resetColor()
end
function Font:applyFilterDoubleBorder(text, x, y, limit, align, r, sx, sy, ox, oy, kx, ky)
love.graphics.setColor(0, 0, 0, 1)
self:printf(text, x-2, y-2, limit, align, r, sx, sy, ox, oy, kx, ky)
self:printf(text, x , y-2, limit, align, r, sx, sy, ox, oy, kx, ky)
self:printf(text, x+2, y-2, limit, align, r, sx, sy, ox, oy, kx, ky)
self:printf(text, x+2, y , limit, align, r, sx, sy, ox, oy, kx, ky)
self:printf(text, x-2, y , limit, align, r, sx, sy, ox, oy, kx, ky)
self:printf(text, x-2, y+2, limit, align, r, sx, sy, ox, oy, kx, ky)
self:printf(text, x , y+2, limit, align, r, sx, sy, ox, oy, kx, ky)
self:printf(text, x+2, y+2, limit, align, r, sx, sy, ox, oy, kx, ky)
utils.draw.resetColor()
end
return Font

View file

@ -0,0 +1,162 @@
local Assets = Object:extend()
local Sprite = require "core.modules.assets.sprites"
local Font = require "core.modules.assets.fonts"
local Tileset = require "core.modules.assets.tileset"
local Autotile = require "core.modules.assets.autotile"
local Background = require "core.modules.assets.background"
function Assets:new()
self.sprites = {}
self.sfx = {}
self.fonts = {}
self.music = nil
self:clearBackgrounds()
self:clearFonts()
self:clearAutotile()
self:clearTileset()
self.images = {}
end
function Assets:init()
self.sprites = {}
self.sfx = {}
self.fonts = {}
self.music = nil
self.backgrounds= {}
self:clearFonts()
self.images = {}
end
function Assets:clear()
self.sprites = {}
self.sfx = {}
self.fonts = {}
self.music = nil
self.backgrounds= {}
self:clearFonts()
self.images = {}
end
function Assets:update(dt)
self:animationsUpdate(dt)
end
-- SFX et Musique
function Assets:addSFX(name, filepath)
self:newSFX(name, filepath)
end
function Assets:newSFX(name, filepath)
self.sfx[name] = love.audio.newSource( filepath, "static" )
end
function Assets:clearSFX()
love.audio.stop( )
self.sfx = {}
end
function Assets:setMusic(filename)
if filename ~= nil then
love.audio.stop( )
self.music = love.audio.newSource(filename, "stream" )
self.music:setVolume(game.options.data.audio.music / 100)
end
end
function Assets:playSFX(filename)
if not (self.sfx[filename] == nil) then
self.sfx[filename]:stop()
self.sfx[filename]:setVolume(game.options.data.audio.sfx / 100)
love.audio.play( self.sfx[filename] )
end
end
function Assets:playMusic()
if not (self.music == nil) then
love.audio.play(self.music)
end
end
function Assets:silence()
love.audio.stop()
end
-- Background --
function Assets:addImage(name, filename)
self.images[name] = love.graphics.newImage(filename)
end
function Assets:drawImage(name, x, y, r, sx, sy, ox, oy, kx, ky)
love.graphics.draw(self.images[name], x, y, r, sx, sy, ox, oy, kx, ky)
end
-- Images --
function Assets:clearBackgrounds()
self.backgrounds = {}
end
function Assets:addBackground(name, filepath)
self.backgrounds[name] = Background(filepath)
end
-- SPRITES --
function Assets:addSprite(name, filepath)
self.sprites[name] = Sprite(filepath)
end
function Assets:clearSprites()
self.sprites = {}
end
function Assets:animationsUpdate(dt)
for i,v in pairs(self.sprites) do
v:update(dt)
end
end
-- FONTS --
function Assets:clearFonts()
self.fonts = {}
end
function Assets:addFont(key, filename, size)
local font = Font(filename, size)
self.fonts[key] = font
end
function Assets:getFont(filename)
return self.fonts[filename]
end
-- Tileset
function Assets:addTileset(name, filepath)
self.tileset[name] = Tileset(filepath)
end
function Assets:clearTileset()
self.tileset = {}
end
-- Autotile
function Assets:addAutotile(name, tilesize)
self.autotile[name] = Autotile(name, tilesize)
end
function Assets:clearAutotile()
self.autotile = {}
end
return Assets

View file

@ -0,0 +1,56 @@
-- Un sprite est un tileset animé par un animateur. Un animateur est nécessairement
-- lié à un sprite, mais on peut en invoqué des différents, suivant les besoins.
local Sprite = Object:extend()
local Animator = require("core.modules.assets.animator")
local Tileset = require("core.modules.assets.tileset")
function Sprite:new(filepath)
self.tileset = Tileset(filepath)
self.data = require(filepath)
self.animator = Animator(self)
self.customSpeed = 0
self:changeToDefaultAnimation(true)
end
function Sprite:update(dt)
self.animator:update(dt)
end
function Sprite:setCustomSpeed(customSpeed)
self.animator:setCustomSpeed(customSpeed)
end
function Sprite:changeToDefaultAnimation(restart)
self.animator:changeToDefaultAnimation(restart)
end
function Sprite:changeAnimation(name, restart)
self.animator:changeAnimation(name, restart)
end
function Sprite:drawAnimation(x, y, r, sx, sy, ox, oy, kx, ky)
self.animator:draw(x, y, r, sx, sy, ox, oy, kx, ky)
end
function Sprite:drawFrame(frame, x, y, r, sx, sy, ox, oy, kx, ky)
self.tileset:drawTile(frame, x, y, r, sx, sy, ox, oy, kx, ky)
end
function Sprite:drawPart(x, y, w, h, r, sx, sy, ox, oy, kx, ky)
local w = math.floor(w)
local h = math.floor(h)
if w >= 0 and h <= 0 then
return 0
end
love.graphics.setScissor(x - ox, y - oy, w, h)
self:drawAnimation(x, y, r, sx, sy, ox, oy, kx, ky)
love.graphics.setScissor( )
end
return Sprite

View file

@ -0,0 +1,69 @@
-- Les tileset sont des découpages de texture automatique en quads. Ils ont
-- l'aventage d'être automatisé, réduisant la quantité de code nécessaire à chaque fois
-- qu'on veut des quads.
-- Ils ont deux façons d'être dessiné : avec leur identifiant de frame (en une dimension)
-- ou en utilisant leur emplacement sur la "grille", en 2D.
-- La grille est un poil plus long, parce que cela nécessite de faire une multiplication
local Tileset = Object:extend()
function Tileset:new(filepath)
self.texture = love.graphics.newImage(filepath .. ".png")
local data = require(filepath)
self.metadata = data.metadata
self:createQuads()
end
function Tileset:createGrid()
self.textureWidth, self.textureHeight = self.texture:getDimensions()
self.width, self.height = self.metadata.width, self.metadata.height
self.gridWidth, self.gridHeight = math.floor(self.textureWidth / self.width),
math.floor(self.textureHeight / self.height)
end
function Tileset:createQuads()
self.quads = {}
self:createGrid()
local quad, n
n = 1
for i=0, (self.gridHeight-1) do
for j=0, (self.gridWidth-1) do
quad = love.graphics.newQuad(j * self.width, i * self.height, self.width, self.height, self.textureWidth, self.textureHeight)
self.quads[n] = quad
n = n + 1
end
end
end
function Tileset:getTileID_Grid(x, y)
local n = (y - 1) * self.gridWidth + x
return n
end
function Tileset:getTile_Grid(x, y)
return self:getTile(self:getTileID_Grid(x, y))
end
function Tileset:getTile(n)
return self.quads[n]
end
function Tileset:drawTile_Grid(i, j, x, y, r, sx, sy, ox, oy, kx, ky)
local tileID = self:getTileID_Grid(i, j)
love.graphics.draw(self.texture, self.quads[tileID], x, y, r, sx, sy, ox, oy, kx, ky)
end
function Tileset:drawTile(id, x, y, r, sx, sy, ox, oy, kx, ky)
love.graphics.draw(self.texture, self.quads[id], x, y, r, sx, sy, ox, oy, kx, ky)
end
return Tileset