improvement(assets): global asset system

Remove the old scene-bound asset system and replace it with a global one. Can lazyload but doesn't do it for the moment.

Fixes #70
!BREAKING
This commit is contained in:
Kazhnuz 2024-10-28 17:19:29 +01:00
parent 1de495f243
commit 4b088dac87
44 changed files with 487 additions and 1122 deletions

View file

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

View file

@ -33,7 +33,6 @@ local MenuWidget = Widget.Text:extend()
function TestScene:new()
TestScene.super.new(self)
self.assets:addImageFont("medium", "assets/fonts/medium")
MenuType(self.menusystem, "testMenu1", 32, 32, 100, 24*8, 4)
MenuWidget(self, "testMenu1", "text_menu1")

View file

@ -31,8 +31,6 @@ local World = require "framework.scenes.world.baseworld"
function TestScene:new()
TestScene.super.new(self)
self.assets:batchImport("scenes.basic.test_scene2.assets")
self.i = 0
self.estImpair = false
@ -67,19 +65,6 @@ end
function TestScene:drawEnd()
love.graphics.setColor(1, 1, 1, 1)
love.graphics.print(math.floor(self.i) .. " ; " .. self.mouse.x .. ":" .. self.mouse.y .. ":" .. self.world:countActors(), 16, 16)
if self.estImpair then
self.assets.images["debris"]:draw(16, 32)
self.assets.tileset["weapon"]:drawTile(3, 32, 32)
self.assets.sprites["poof"]:drawAnimation(64, 32)
else
love.graphics.setColor(0, 1, 0, 1)
self.assets.images["debris"]:drawMask(16, 32)
self.assets.tileset["weapon"]:drawTileMask(3, 32, 32)
self.assets.sprites["poof"]:drawAnimationMask(64, 32)
utils.graphics.resetColor()
end
end
return TestScene

View file

@ -31,7 +31,6 @@ function MovePlayer:new(playerNumber, cameraMode)
local cameraMode = cameraMode or "split"
MovePlayer.super.new(self)
self.assets:batchImport("scenes.gameplay.plateform.assets")
World(self, "scenes.gameplay.action3D.actors", "datas/maps/action3D/map.lua")

View file

@ -31,7 +31,6 @@ function MovePlayer:new(playerNumber, cameraMode)
local cameraMode = cameraMode or "split"
MovePlayer.super.new(self)
self.assets:batchImport("scenes.gameplay.plateform.assets")
World(self, "scenes.gameplay.moveplayer3D.actors", "datas/maps/topdown/arena.lua")

View file

@ -7,7 +7,8 @@ function Coin:new(world, x, y)
end
function Coin:takeCoin(other)
self.obj.GFX(self.world, self.x + 8, self.y + 8, "sparkle")
self.obj.GFX(self.world, self.x + 8, self.y + 8, "gfx.sparkle")
assets:playSFX("gameplay.collectcoin")
self:destroy( )
end

View file

@ -3,7 +3,7 @@ local Player = Base:extend()
function Player:new(world, x, y, id)
Player.super.new(self, world, "player", x, y, 16, 24, true)
self:setSprite("player", true, 8, 12)
self:setSprite("monkey_lad", true, 8, 12)
self:setGravity(480)
self.isPunching = false
@ -20,6 +20,7 @@ function Player:updateStart(dt)
if self.keys["up"].isPressed and (self.onGround) then
self.ysp = -280
assets:playSFX("gameplay.jump")
end
if self.keys["down"].isDown then
self.mainHitbox:modify(0, 8, 16, 16)
@ -44,8 +45,6 @@ function Player:updateStart(dt)
end
if self.keys["start"].isPressed then
--self.world:switchActivity()
--self.assets:switchActivity()
self.scene.menusystem:activate()
self.scene.menusystem:switchMenu("PauseMenu")
self.scene:flushKeys()

View file

@ -32,8 +32,6 @@ function Plateformer:new()
local folder = "scenes.gameplay.plateform"
self.assets:batchImport("scenes.gameplay.plateform.assets")
World(self, folder .. ".actors", "datas/maps/plateformer/platformer.lua")
--Pause(self)

View file

@ -31,7 +31,7 @@ function ResumeWidget:new()
end
function ResumeWidget:action()
self.scene.assets:playSFX(self.sfx)
assets:playSFX(self.sfx)
self.scene.menusystem:deactivate()
end
@ -42,7 +42,7 @@ function RestartWidget:new()
end
function RestartWidget:action()
self.scene.assets:playSFX(self.sfx)
assets:playSFX(self.sfx)
self.scene:restart()
end
@ -53,7 +53,7 @@ function ExitWidget:new()
end
function ExitWidget:action()
self.scene.assets:playSFX(self.sfx)
assets:playSFX(self.sfx)
core.scenemanager:setStoredScene("mainmenu")
end

View file

@ -28,7 +28,6 @@ local Menu = require "scenes.mainmenu.menu"
function MainMenu:new()
MainMenu.super.new(self, true, true)
self.assets:batchImport("scenes.mainmenu.assets")
Menu(self)
end

View file

@ -34,8 +34,6 @@ local ExitWidget = Widget.Text:extend()
function Inventory:new()
Inventory.super.new(self)
self.assets:addImageFont("medium", "assets/fonts/medium")
HListBox(self.menusystem, "main", 42, 32, 424-84, 32, 5)
self:addSubMenu("weapon", "weapons")
@ -87,7 +85,7 @@ end
function InventoryWidget:new(scene, menu, newmenu, fullname)
self.scene = scene
local widgetmenu = self.scene.menusystem.menus[menu]
local font = self.scene.assets.fonts["medium"]
local font = "medium"
self.newmenu = newmenu
local label = core.lang:translate("inventory", fullname)
InventoryWidget.super.new(self, widgetmenu, font, label)
@ -105,7 +103,7 @@ end
function ItemWidget:new(scene, menu, id)
self.scene = scene
local widgetmenu = self.scene.menusystem.menus[menu]
local font = self.scene.assets.fonts["medium"]
local font = "medium"
ItemWidget.super.new(self, widgetmenu, font, id)
end
@ -118,7 +116,7 @@ end
function ExitWidget:new(scene, menu)
self.scene = scene
local widgetmenu = self.scene.menusystem.menus[menu]
local font = self.scene.assets.fonts["medium"]
local font = "medium"
local label = core.lang:translate("commons", "exit")
ExitWidget.super.new(self, widgetmenu, font, label)
end

View file

@ -31,14 +31,8 @@ local consts = require "scenes.menus.options.consts"
function OptionsMenu:start()
OptionsMenu.super.new(self)
self.assets:addImageFont("medium", "assets/fonts/medium")
self.assets:setMusic("assets/music/options.ogg")
self.assets:addSFX("navigate", "assets/sfx/menu_move.mp3")
self.assets:addSFX("confirm", "assets/sfx/menu_confirm.mp3")
self.assets:addSFX("cancel", "assets/sfx/menu_error.mp3")
self.assets:playMusic()
assets:playMusic("options")
self.menu = Menu("medium");

View file

@ -59,7 +59,7 @@ function widgets.SubMenu:new(scene, newmenu, fullname, order, label2)
end
function widgets.SubMenu:action()
self.scene.assets:playSFX("confirm")
assets:playSFX("menu_confirm")
self.menu:switch(self.newmenu)
end
@ -83,7 +83,7 @@ function widgets.Exit:new(scene, menu)
end
function widgets.Exit:action()
self.assets:playSFX("confirm")
assets:playSFX("menu_confirm")
core.scenemanager:setStoredScene("mainmenu")
end
@ -137,7 +137,7 @@ end
function widgets.Switch:action()
self:modifyKey()
local scene = core.scenemanager:getScene()
scene.assets:playSFX("confirm")
assets:playSFX("menu_confirm")
self:replaceLabel(2, self:getLabel())
core.options:write()
self:invalidateCanvas()
@ -164,7 +164,7 @@ function widgets.Resolution:action()
self:replaceLabel(2, self:getLabel())
core.screen:applySettings()
local scene = core.scenemanager:getScene()
scene.assets:playSFX("confirm")
assets:playSFX("menu_confirm")
self:invalidateCanvas()
core.options:write()
end
@ -180,7 +180,7 @@ end
function widgets.Lang:action()
local scene = core.scenemanager:getScene()
scene.assets:playSFX("confirm")
assets:playSFX("menu_confirm")
core.options:setLanguage(self.lang)
--self.scene.menusystem:invalidateAllWidgets()
end
@ -199,7 +199,7 @@ end
function widgets.PlayerSubMenu:action()
local scene = core.scenemanager:getScene()
scene.assets:playSFX("confirm")
assets:playSFX("menu_confirm")
scene.menusystem:switchMenu(self.newmenu)
end
@ -224,14 +224,14 @@ end
function widgets.Key:action()
local scene = core.scenemanager:getScene()
scene.assets:playSFX("navigate")
assets:playSFX("navigate")
scene:changeKey(self)
scene.menusystem:deactivate()
end
function widgets.Key:receiveKey( key )
local scene = core.scenemanager:getScene()
scene.assets:playSFX("confirm")
assets:playSFX("menu_confirm")
core.options:setInputKey(self.source, self.key, key)
self:replaceLabel(2, self:getLabel())
self:invalidateCanvas()
@ -290,7 +290,7 @@ function widgets.Audio:action()
local value = self:getVolume()
self:setVolume(value - 20)
local scene = core.scenemanager:getScene()
scene.assets:playSFX("confirm")
assets:playSFX("menu_confirm")
core.music:applyVolume()
core.options:write()
end

View file

@ -0,0 +1,79 @@
-- assets/containers/parent.lua :: A basic asset container
--[[
Copyright © 2024 Kazhnuz
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
]]
local AssetContainer = Object:extend()
function AssetContainer:new(assetType, checkFor, loader, preload)
self.type = assetType
self.preload = preload
self.checkFor = checkFor
self.loader = loader
self.pathes = {}
self.list = {}
self:scanFolder(folder, parent)
end
function AssetContainer:scanFolder(folder, parent)
local prefix = "assets/" .. self.type
local folder = folder or ""
local parent = parent or ""
local path = prefix .. "/" .. folder
files = love.filesystem.getDirectoryItems( path )
for i, file in ipairs(files) do
local filepath = path .. file
if (love.filesystem.getInfo( filepath ).type == "file" ) then
local data = love.filesystem.newFileData( filepath )
local extension = data:getExtension()
local fileName = string.sub(file, 1, #file - #extension - 1)
if (utils.table.contain(self.checkFor, extension)) then
self.pathes[parent .. fileName] = {path = filepath, extension = extension, canonical = path .. fileName}
if (self.preload) then
self:load(parent .. fileName)
end
end
else
self:scanFolder(folder .. file .. "/", parent .. file .. ".")
end
end
end
function AssetContainer:load(id)
assert(id ~= nil, "AssetContainer:load shoudln't be called with a nil id")
assert(id ~= "", "AssetContainer:load shoudln't be called with an empty id")
assert(self.pathes[id] ~= nil, "Asset " .. self.type .. " " .. id .. " doesn't exist")
if (self.list[id] == nil) then
self.loader(self.list, id, self.pathes[id])
end
end
function AssetContainer:get(id)
self:load(id)
return self.list[id]
end
return AssetContainer

69
framework/assets/init.lua Normal file
View file

@ -0,0 +1,69 @@
-- assets/init.lua :: The main file of the asset manager, an object that'll handle
-- all assets of the framework. It's disconnected of screens, but can handle some assets
-- from their caller in lazyloading mode
--[[
Copyright © 2024 Kazhnuz
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
]]
local AssetManager = Object:extend()
local AssetContainer = require "framework.assets.containers"
local loaders = require "framework.assets.loaders"
function AssetManager:new(preload)
self.sfx = AssetContainer("sfx", {"mp3", "ogg", "wav"}, loaders.sfx, preload)
self.textures = AssetContainer("textures", {"png", "jpg", "webp"}, loaders.textures, preload)
self.music = AssetContainer("music", {"mp3", "ogg", "wav"}, loaders.music, false)
self.fonts = AssetContainer("fonts", {"png", "ttf"}, loaders.fonts, preload)
self.sprites = AssetContainer("sprites", {"png"}, loaders.sprites, preload)
end
function AssetManager:playSFX(id)
local sfx = self.sfx:get(id)
sfx:stop()
sfx:setVolume(core.options.data.audio.sfx / 100)
love.audio.play(sfx)
end
function AssetManager:stopSFX(id)
local sfx = self.sfx:get(id)
sfx:stop()
end
function AssetManager:setFont(font)
love.graphics.setFont(self.fonts:get(font))
end
function AssetManager:print(font, text, x, y, align, r, sx, sy, ox, oy, kx, ky)
self:setFont(font)
utils.graphics.print(text, x, y, align, r, sx, sy, ox, oy, kx, ky)
end
function AssetManager:printf(font, text, x, y, limit, align, r, sx, sy, ox, oy, kx, ky)
self:setFont(font)
if (limit > 0) then
love.graphics.printf(text, x, y, limit, align, r, sx, sy, ox, oy, kx, ky)
else
utils.graphics.print(text, x, y, align, r, sx, sy, ox, oy, kx, ky)
end
end
return AssetManager

View file

@ -0,0 +1,42 @@
local loaders = {}
local Sprite = require "framework.assets.type.sprite"
local Tileset = require "framework.assets.type.tileset"
function loaders.sfx(list, id, data)
list[id] = love.audio.newSource(data.path, "static")
end
function loaders.textures(list, id, data)
list[id] = love.graphics.newImage(data.path)
end
function loaders.music(list, id, data)
list[id] = love.audio.newSource(data.path, "stream")
end
function loaders.fonts(list, id, data)
local metadata = require ("assets.fonts." .. id)
if (data.extension == "ttf") then
list[id] = love.graphics.newFont(data.path, metadata.default)
if (metadata.sizes ~= nil) then
for i, size in ipairs(metadata.sizes) do
list[id .. "." .. size] = love.graphics.newFont(data.path, size)
end
end
else
list[id] = love.graphics.newImageFont(data.path, metadata.glyphs, metadata.extraspacing or 1)
end
end
function loaders.sprites(list, id, data)
local spriteData = require ("assets.sprites." .. id)
list[id] = Sprite(data.path, spriteData)
end
function loaders.tilesets(list, id, data)
local tilesetData = require ("assets.sprites." .. id)
list[id] = Tileset(data.path, tilesetData)
end
return loaders

View file

@ -0,0 +1,150 @@
-- assets/sprite :: the assets object, which is basically a tileset with animation
-- and frame metadata
--[[
Copyright © 2019 Kazhnuz
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
]]
local Sprite = Object:extend()
local Tileset = require "framework.assets.type.tileset"
-- INIT FUNCTIONS
-- Initilizing and configuring option
function Sprite:new(filepath, data)
self.tileset = Tileset(filepath, data)
self.data = data
end
-- INFO FUNCTIONS
-- get information with these functions
function Sprite:getDefaultAnimation()
return self.data.metadata.defaultAnim
end
function Sprite:getAbsoluteFrame(animation, subframe)
return self.data.animations[animation].startAt + subframe
end
function Sprite:getAnimationData(animation)
return self.data.animations[animation]
end
function Sprite:getAnimationLenght(animation)
local animationData = self:getAnimationData(animation)
if (animationData.lenght ~= nil) then
return animationData.lenght
else
return (animationData.endAt - animationData.startAt)
end
end
function Sprite:getAnimationSpeed(animation, custom)
local animationData = self:getAnimationData(animation)
if (animationData.speed ~= nil and animationData.speed >= 0) then
return animationData.speed
end
return custom or 0
end
function Sprite:isAnimationOver(animation, frame)
return frame >= self:getAnimationLenght(animation)
end
function Sprite:getAnimationRestartFrame(animation)
local animationData = self:getAnimationData(animation)
if (animationData.pauseAtEnd == true) then
return self:getAnimationLenght() - 1
end
if (animationData.restart ~= nil) then
return (animationData.restart)
elseif (animationData.restartAt ~= nil) then
return (animationData.restartAt - animationData.startAt)
elseif (animationData.loop ~= nil) then
return (animationData.loop - animationData.startAt)
else
return 0
end
end
function Sprite:getAnimationDuration(animation)
local animationData = self:getAnimationData(animation)
return (self:getAnimationLenght(animation)) / animationData.speed
end
function Sprite:animationExist(name)
return (self:getAnimationData(name) ~= nil)
end
function Sprite:getFrameSignal(animation, frame)
local animationData = self:getAnimationData(animation)
if (animationData.signal == nil or type(animationData.signal ~= "table")) then
return {}
end
local signals = {}
if (type(animationData.signal[1]) ~= "table" and animationData.signal[1] == frame) then
-- Si le premier élément de la liste signal n'est pas une table, cela veut dire que le signal est de la forme {frame, signal}
table.insert(signals, animationData.signal[2])
else
-- Sinon cela veut dire que le signal est de la forme {{frame1, signal1}, {frame2, signal2}}
for _, signal in ipairs(animationData.signal) do
if (signal[1] == frame) then
table.insert(signals, signal[2])
end
end
end
return signals
end
function Sprite:getDimensions()
return self.tileset:getDimensions()
end
-- DRAW FUNCTIONS
-- Draw sprites using these functions
function Sprite:draw(animation, frame, x, y, r, sx, sy, ox, oy, kx, ky)
self.tileset:drawTile(self:getAbsoluteFrame(animation, frame), x, y, r, sx, sy, ox, oy, kx, ky)
end
function Sprite:drawPart(animation, frame, 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:draw(animation, frame, x, y, r, sx, sy, ox, oy, kx, ky)
love.graphics.setScissor( )
end
return Sprite

View file

@ -27,17 +27,12 @@
]]
local Tileset = Object:extend()
local cwd = (...):gsub('%.tileset$', '') .. "."
local Texture = require(cwd .. "texture")
-- INIT FUNCTIONS
-- Initilizing and configuring option
function Tileset:new(filepath)
self.texture = Texture(filepath .. ".png")
local data = require(filepath)
function Tileset:new(filepath, data)
self.texture = love.graphics.newImage(filepath)
self.metadata = data.metadata
self:createQuads()
@ -53,7 +48,6 @@ end
function Tileset:createQuads()
self.quads = {}
self:createGrid()
local quad, n
@ -72,18 +66,16 @@ end
-- INFO FUNCTIONS
-- get information with these functions
function Tileset:getTileID_Grid(x, y)
local n = (y - 1) * self.gridWidth + x
return n
function Tileset:_coordToTileID(x, y)
return (y - 1) * self.gridWidth + x
end
function Tileset:getTile_Grid(x, y)
return self:getTile(self:getTileID_Grid(x, y))
end
function Tileset:getTile(n)
return self.quads[n]
function Tileset:getTile(id)
if (type(id) == "number") then
return self.quads[id]
else
return self.quads[self:_coordToTileID(id.x, id.y)]
end
end
function Tileset:getDimensions()
@ -93,28 +85,12 @@ end
-- DRAW FUNCTIONS
-- Draw tileset using these functions
function Tileset:drawTile_Grid(i, j, x, y, r, sx, sy, ox, oy, kx, ky)
local tileID = self:getTileID_Grid(i, j)
local ox = ox or self.metadata.ox
local oy = oy or self.metadata.oy
self.texture:drawQuad(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)
assert(id ~= nil, "id is nil")
assert(self:getTile(id) ~= nil, "Tile id " .. id .. " doesn't exists");
local ox = ox or self.metadata.ox
local oy = oy or self.metadata.oy
self.texture:drawQuad(self.quads[id], x, y, r, sx, sy, ox, oy, kx, ky)
end
function Tileset:drawTileMask_Grid(i, j, x, y, r, sx, sy, ox, oy, kx, ky)
local tileID = self:getTileID_Grid(i, j)
local ox = ox or self.metadata.ox
local oy = oy or self.metadata.oy
self.texture:drawMaskQuad(self.quads[tileID], x, y, r, sx, sy, ox, oy, kx, ky)
end
function Tileset:drawTileMask(id, x, y, r, sx, sy, ox, oy, kx, ky)
self.texture:drawMaskQuad(self.quads[id], x, y, r, sx, sy, ox, oy, kx, ky)
love.graphics.draw(self.texture, self:getTile(id), x, y, r, sx, sy, ox, oy, kx, ky)
end
return Tileset

View file

@ -32,6 +32,8 @@ Object = require("framework.libs.classic")
utils = require("framework.utils")
enum = require("framework.utils.enum")
Assets = require("framework.assets")
framework.Core = require("framework.core")
function framework.start(gamemodule, args)
@ -39,6 +41,8 @@ function framework.start(gamemodule, args)
if (gamemodule ~= nil) then
framework.startGame(gamemodule)
end
assets = Assets(true)
end
function framework.startCore(args)

View file

@ -27,12 +27,12 @@ local Animator = Object:extend()
-- INIT FUNCTIONS
-- Initilizing and configuring option
function Animator:new(sprite)
self.sprite = sprite
self.frame = 1
function Animator:new(name)
self.name = name
self.sprite = assets.sprites:get(name)
self.frame = 0
self.frameTimer = 0
self.currentAnimation = ""
self.animationData = {}
self.customSpeed = 0
self.speedFactor = 1
@ -57,21 +57,18 @@ function Animator:update(dt)
return 0
end
local speed = self.animationData.speed
if (self.animationData.speed) == -1 then
speed = self.customSpeed --math.abs(self.xsp / 16)
end
local speed = self.sprite:getAnimationSpeed(self.currentAnimation, self.customSpeed)
self.frameTimer = self.frameTimer + (speed * dt * self.speedFactor)
if self.frameTimer > 1 then
self.frameTimer = 0
if self.frame == self.animationData.endAt then
if not (self.animationData.pauseAtEnd) then
self.frame = self.animationData.loop
end
self:sendCallback()
if (self.sprite:isAnimationOver(self.currentAnimation, self.frame)) then
self.frame = self.sprite:getAnimationRestartFrame(self.currentAnimation)
self:sendCallback()
else
self.frame = self.frame + 1
self:sendFrameSignal()
self.frame = self.frame + 1
self:sendFrameSignal()
end
end
end
@ -88,16 +85,15 @@ function Animator:changeAnimation(name, restart)
end
self.currentAnimation = name
self.animationData = self.sprite.data.animations[self.currentAnimation]
if (restart == true) then
self.frame = self.animationData.startAt
self.frame = 0
self.frameTimer = 0
end
end
function Animator:changeToDefaultAnimation(restart)
self:changeAnimation(self.sprite.data.metadata.defaultAnim, restart)
self:changeAnimation(self.sprite:getDefaultAnimation(), restart)
end
-- INFO FUNCTIONS
@ -108,19 +104,15 @@ function Animator:getCurrentAnimation()
end
function Animator:getAnimationDuration(animation)
return (self.animationData.endAt - self.animationData.startAt) / self.animationData.speed
return self.sprite:getAnimationDuration(animation)
end
function Animator:getFrame()
return self.frame
end
function Animator:getRelativeFrame()
return self.frame - (self.animationData.startAt) + 1
function Animator:getAbsoluteFrame()
return self.sprite:getAbsoluteFrame()
end
function Animator:animationExist(name)
return (self.sprite.data.animations[self.currentAnimation] ~= nil)
return self.sprite:animationExist(name)
end
function Animator:getDimensions()
@ -131,7 +123,7 @@ end
-- Handle getting a calback from the animation system
function Animator:setCallbackTarget(actor)
self.actor = actor
self.callbackTarget = actor
end
function Animator:setCallback(actor)
@ -140,26 +132,24 @@ function Animator:setCallback(actor)
end
function Animator:sendCallback()
if (self.actor ~= nil) then
self.actor:animationEnded(self.currentAnimation)
if (self.callbackTarget ~= nil) then
self.callbackTarget:animationEnded(self.currentAnimation)
end
end
function Animator:sendFrameSignal()
if (self.animationData.signal ~= nil) then
if (type(self.animationData.signal[1]) ~= "table") then
self:trySendSignal(self:getRelativeFrame(), self.animationData.signal)
else
for _, signal in ipairs(self.animationData.signal) do
self:trySendSignal(self:getRelativeFrame(), signal)
end
local signals = self.sprite:getFrameSignal(self.currentAnimation, self.frame)
if (signals ~= nil and #signals > 0) then
for _, signal in ipairs(signals) do
self:trySendSignal(signal)
end
end
end
end
function Animator:trySendSignal(frame, signal)
if (signal[1] == frame) and (self.actor ~= nil) and (self.actor.receiveFrameSignal ~= nil) then
self.actor:receiveFrameSignal(signal[2])
if (self.callbackTarget ~= nil) and (self.callbackTarget.receiveFrameSignal ~= nil) then
self.callbackTarget:receiveFrameSignal(signal)
end
end
@ -167,11 +157,7 @@ end
-- Draw animations using these functions
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:drawMask(x, y, r, sx, sy, ox, oy, kx, ky)
self.sprite:drawFrameMask(self.frame, x, y, r, sx, sy, ox, oy, kx, ky)
self.sprite:draw(self.currentAnimation, self.frame, x, y, r, sx, sy, ox, oy, kx, ky)
end
return Animator

View file

@ -1,7 +1,8 @@
-- assets/sfx :: the sfx object
-- scenes/animators :: the animator manager. Create on demand animators and can clone
-- them
--[[
Copyright © 2021 Kazhnuz
Copyright © 2024 Kazhnuz
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
@ -20,31 +21,38 @@
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
]]
local SFX = Object:extend()
-- INIT FUNCTIONS
-- Initilizing and configuring option
local AnimatorManager = Object:extend()
local Animator = require "framework.scenes.animators.animator"
function SFX:new(filepath)
self.source = love.audio.newSource(filepath, "static")
function AnimatorManager:new()
self.list = {}
end
-- INFO FUNCTIONS
-- get information with these functions
-- None for the moment
-- DRAW FUNCTIONS
-- Draw texture using these functions
function SFX:play()
self.source:stop()
self.source:setVolume(core.options.data.audio.sfx / 100)
love.audio.play(self.source)
function AnimatorManager:update(dt)
for _, animator in pairs(self.list) do
animator:update(dt)
end
end
function SFX:stop()
self.source:stop()
function AnimatorManager:init(name)
if (self.list[name] == nil) then
self.list[name] = Animator(name)
end
end
return SFX
function AnimatorManager:get(name)
self:init(name)
return self.list[name]
end
function AnimatorManager:clone(name)
return Animator(name)
end
function AnimatorManager:draw(name, x, y, r, sx, sy, ox, oy, kx, ky)
local animator = self:get(name)
animator:draw(x, y, r, sx, sy, ox, oy, kx, ky)
end
return AnimatorManager

View file

@ -1,297 +0,0 @@
-- modules/assets :: a simple assets manager, aim to put every assets in a simple
-- serie of table in order to find them easily.
--[[
Copyright © 2019 Kazhnuz
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
]]
local Assets = Object:extend()
local cwd = (...):gsub('%.init$', '') .. ".types."
local Texture = require(cwd .. "texture")
local Sprite = require(cwd .. "sprites")
local Font = require(cwd .. "fonts")
local ImageFont = require(cwd .. "imagefonts")
local Tileset = require(cwd .. "tileset")
local Autotile = require(cwd .. "autotile")
local Background = require(cwd .. "background")
local SFX = require(cwd .. "sfx")
-- INIT FUNCTIONS
-- Initilizing and configuring option
function Assets:new()
self:clear()
self.isActive = true
end
function Assets:clear()
-- TODO: destroy individually each texture/image when assets are cleared
self:clearSprites()
self:clearSFX()
self:clearFonts()
self:resetMusic()
self:clearBackgrounds()
self:clearFonts()
self:clearTileset()
self:clearImages()
end
function Assets:update(dt)
if (self.isActive) then
self:animationsUpdate(dt)
end
end
-- IMPORT FUNCTIONS
-- Easilly import assets
function Assets:batchImport(datafile)
local datas = require(datafile)
for asset_type, assets in pairs(datas) do
if (asset_type == "autotiles") then
self:importAutotiles(assets)
elseif (asset_type == "backgrounds") then
self:importBackgrounds(assets)
elseif (asset_type == "fonts") then
self:importFonts(assets)
elseif (asset_type == "imagefonts") then
self:importImageFonts(assets)
elseif (asset_type == "images") then
self:importTextures(assets)
elseif (asset_type == "sprites") then
self:importSprites(assets)
elseif (asset_type == "textures") then
self:importTextures(assets)
elseif (asset_type == "tilesets") then
self:importTilesets(assets)
elseif (asset_type == "sfx") then
self:importSFX(assets)
else
core.debug:warning("assets/importer", "unkown asset type " .. asset_type)
end
end
end
function Assets:importAutotiles(assets)
for i, asset in ipairs(assets) do
self:addAutotile(asset[1], asset[2])
end
end
function Assets:importBackgrounds(assets)
for i, asset in ipairs(assets) do
self:addBackground(asset[1], asset[2])
end
end
function Assets:importFonts(assets)
for i, asset in ipairs(assets) do
self:addFont(asset[1], asset[2], asset[3])
end
end
function Assets:importImageFonts(assets)
for i, asset in ipairs(assets) do
self:addImageFont(asset[1], asset[2], asset[3])
end
end
function Assets:importSprites(assets)
for i, asset in ipairs(assets) do
self:addSprite(asset[1], asset[2])
end
end
function Assets:importTextures(assets)
for i, asset in ipairs(assets) do
self:addImage(asset[1], asset[2])
end
end
function Assets:importTilesets(assets)
for i, asset in ipairs(assets) do
self:addTileset(asset[1], asset[2])
end
end
function Assets:importSFX(assets)
for i, asset in ipairs(assets) do
self:addSFX(asset[1], asset[2])
end
end
-- SFX & MUSICS
-- Handle sound effects and musics
function Assets:addSFX(name, filepath)
self:newSFX(name, filepath)
end
function Assets:newSFX(name, filepath)
self.sfx[name] = SFX( filepath )
end
function Assets:clearSFX()
love.audio.stop( )
self.sfx = {}
end
function Assets:playSFX(filename)
if not (self.sfx[filename] == nil) then
self.sfx[filename]:play()
end
end
-- MUSIC FUNCTIONS
-- All thse functions are deprecated, prefer core.music
function Assets:setMusic(filename, loop)
core.debug:warning("assets", "Assets:setMusic is deprecated")
core.music:skip()
core.music:addMusic(filename, (loop ~= false))
core.music:playMusic()
end
function Assets:silence()
core.debug:warning("assets", "Assets:silence is deprecated")
core.music:silence()
end
function Assets:resetMusic()
core.debug:warning("assets", "Assets:resetMusic is deprecated")
core.music:purge()
end
function Assets:playMusic()
core.debug:warning("assets", "Assets:playMusic is deprecated")
core.music:playMusic()
end
-- IMAGES FUNCTIONS
-- Create directly texture items
function Assets:addImage(name, filename)
self.images[name] = Texture(filename)
end
function Assets:drawImage(name, x, y, r, sx, sy, ox, oy, kx, ky)
self.images[name]:draw(x, y, r, sx, sy, ox, oy, kx, ky)
end
function Assets:clearImages()
self.images = {}
end
-- BACKGROUNDS FUNCTIONS
-- Automatic tiling texture
function Assets:addBackground(name, filepath)
-- TODO: rework entirely background to work at any size
self.backgrounds[name] = Background(filepath)
end
function Assets:clearBackgrounds()
self.backgrounds = {}
end
-- SPRITES FUNCTIONS
-- Animated tileset
function Assets:addSprite(name, filepath)
self.sprites[name] = Sprite(filepath)
end
function Assets:animationsUpdate(dt)
for i,v in pairs(self.sprites) do
v:update(dt)
end
end
function Assets:clearSprites()
self.sprites = {}
end
-- FONTS FUNCTIONS
-- Handles fonts and imagesfonts
function Assets:addFont(key, filename, size)
local font = Font(filename, size)
self.fonts[key] = font
end
function Assets:addImageFont(key, filename, extraspacing)
local font = ImageFont(filename, extraspacing)
self.fonts[key] = font
end
function Assets:getFont(filename)
return self.fonts[filename]
end
function Assets:clearFonts()
self.fonts = {}
end
-- TILESET FUNCTIONS
-- Automatically create quads for a texture
function Assets:addTileset(name, filepath)
self.tileset[name] = Tileset(filepath)
end
function Assets:clearTileset()
self.tileset = {}
end
-- AUTOTILE FUNCTIONS
-- Automatically draw tiles
function Assets:addAutotile(name, tilesize)
self.autotile[name] = Autotile(name, tilesize)
end
function Assets:clearAutotile()
self.autotile = {}
end
-- ACTIVITY FUNCTIONS
-- Handle activity
function Assets:setActivity(activity)
self.isActive = activity
end
function Assets:switchActivity()
self.isActive = (self.isActive == false)
end
function Assets:getActivity()
return self.isActive
end
return Assets

View file

@ -1,117 +0,0 @@
-- assets/autotile :: The autotile object : this is an object that draw tiles
-- automatically with borders in rectangles.
-- It works with a 3×3 tileset showing all borders.
--[[
Copyright © 2019 Kazhnuz
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
]]
local cwd = (...):gsub('%.autotile$', '') .. "."
local Tileset = require(cwd .. "tileset")
local Autotile = Object:extend()
-- INIT FUNCTIONS
-- Initilizing and configuring option
function Autotile:new(filepath)
self.tileset = Tileset(filepath)
self.data = require(filepath .. ".lua")
self.metadata = self.data.metadata
self.tilesize = self.metadata.width
end
-- DRAW FUNCTIONS
-- Draw tileset using these functions
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

@ -1,54 +0,0 @@
-- assets/sprite :: the background object, which is an image that draw itself
-- automatically to fill a texture.
--[[
Copyright © 2019 Kazhnuz
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
]]
local Background = Object:extend()
-- INIT FUNCTIONS
-- Initilizing and configuring option
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 screenwidth, screenheight = core.screen:getDimensions()
local w = math.floor(screenwidth / self.width) * self.width + 1
local h = math.floor(screenheight / 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

@ -1,182 +0,0 @@
-- assets/fonts :: the fonts object, which is a simple way to draw text with font.
-- Some of these functions are quite slow, so it's better to use them to generate
-- texture instead of text.
--[[
Copyright © 2019 Kazhnuz
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
]]
local Font = Object:extend()
-- INIT FUNCTIONS
-- 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
-- INFO FUNCTIONS
-- get information with these 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
-- DRAW FUNCTIONS
-- print text using theses 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.graphics.printWithSpacing(text, x, y, self.spacing.size, align, r, sx, sy, ox, oy, kx, ky)
else
utils.graphics.print(text, x, y, align, 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
-- With these filter, you can apply custom effects to the fonts
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, self.color.a)
self:printf(text, x+1, y+1, limit, align, r, sx, sy, ox, oy, kx, ky)
utils.graphics.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.graphics.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.graphics.resetColor()
end
return Font

View file

@ -1,43 +0,0 @@
-- assets/fonts :: the imagefonts object, which are basically a bitmap version
-- of the font object.
--[[
Copyright © 2019 Kazhnuz
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
]]
local cwd = (...):gsub('%.imagefonts$', '') .. "."
local Font = require(cwd.. "fonts")
local ImageFont = Font:extend()
-- INIT FUNCTIONS
-- Initilizing and configuring option
function ImageFont:new(filename, extraspacing)
local data = require(filename)
local extraspacing = extraspacing or data.extraspacing or 1
self.font = love.graphics.newImageFont(filename .. ".png", data.glyphs, extraspacing)
self.filter = ""
self:setColor(1, 1, 1, 1)
self:setSpacing(false, 0)
self.align = "left"
end
return ImageFont

View file

@ -1,129 +0,0 @@
-- assets/sprite :: the assets object, which is basically a tileset animated by
-- an animator object. An animator object is always tied to a sprite, but a sprite
-- can use different animator in order to make several animator share the same sprite
--[[
Copyright © 2019 Kazhnuz
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
]]
local Sprite = Object:extend()
local cwd = (...):gsub('%.sprites$', '') .. "."
local Animator = require(cwd .. "animator")
local Tileset = require(cwd .. "tileset")
-- INIT FUNCTIONS
-- Initilizing and configuring option
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:clone()
return Animator(self)
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:setSpeedFactor(speedFactor)
self.animator:setSpeedFactor(speedFactor)
end
-- INFO FUNCTIONS
-- get information with these functions
function Sprite:getCurrentAnimation()
return self.animator:getCurrentAnimation()
end
function Sprite:animationExist(name)
return self.animator:animationExist(name)
end
function Sprite:getDimensions()
return self.tileset:getDimensions()
end
function Sprite:getFrame()
return self.animator:getFrame()
end
function Sprite:getAnimationDuration(animation)
return self.animator:getAnimationDuration(animation)
end
function Sprite:getRelativeFrame()
return self.animator:getRelativeFrame()
end
-- DRAW FUNCTIONS
-- Draw sprites using these functions
function Sprite:draw(x, y, r, sx, sy, ox, oy, kx, ky)
self.animator:draw(x, y, r, sx, sy, ox, oy, kx, ky)
end
function Sprite:drawMask(x, y, r, sx, sy, ox, oy, kx, ky)
self.animator:drawMask(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:drawFrameMask(frame, x, y, r, sx, sy, ox, oy, kx, ky)
self.tileset:drawTileMask(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:draw(x, y, r, sx, sy, ox, oy, kx, ky)
love.graphics.setScissor( )
end
return Sprite

View file

@ -1,74 +0,0 @@
-- assets/texture :: the texture object, essentially used to be able to draw easily
-- the mask of the texture (used for stuff like flashing sprite, etc)
--[[
Copyright © 2019 Kazhnuz
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
]]
local Texture = Object:extend()
local function getMask(x, y, r, g, b, a)
-- template for defining your own pixel mapping function
-- perform computations giving the new values for r, g, b and a
-- ...
return 1, 1, 1, a
end
-- INIT FUNCTIONS
-- Initilizing and configuring option
function Texture:new(filename)
self.imageData = love.image.newImageData(filename)
local maskData = self.imageData:clone()
maskData:mapPixel( getMask )
self.image = love.graphics.newImage( self.imageData )
self.mask = love.graphics.newImage( maskData )
end
-- INFO FUNCTIONS
-- get information with these functions
function Texture:getDimensions()
return self.image:getDimensions()
end
-- DRAW FUNCTIONS
-- Draw texture using these functions
function Texture:draw(x, y, r, sx, sy, ox, oy, kx, ky)
love.graphics.draw(self.image, x, y, r, sx, sy, ox, oy, kx, ky)
end
function Texture:drawQuad(quad, x, y, r, sx, sy, ox, oy, kx, ky)
love.graphics.draw(self.image, quad, x, y, r, sx, sy, ox, oy, kx, ky)
end
function Texture:drawMask(x, y, r, sx, sy, ox, oy, kx, ky)
love.graphics.draw(self.mask, x, y, r, sx, sy, ox, oy, kx, ky)
end
function Texture:drawMaskQuad(quad, x, y, r, sx, sy, ox, oy, kx, ky)
love.graphics.draw(self.mask, quad, x, y, r, sx, sy, ox, oy, kx, ky)
end
return Texture

View file

@ -3,7 +3,7 @@ local AssetElement = Parent:extend()
function AssetElement:new(name, assetType, assetName, x, y,r,sx,sy,ox,oy, opacity)
self:initWrapper()
local asset = self.assets[assetType][assetName]
local asset = assets[assetType].get(assetName)
assert(asset ~= nil, assetName .. ' (' .. assetType .. ") doesn't exist")
AssetElement.super.new(self, name, asset, x, y,r,sx,sy,ox,oy, opacity)

View file

@ -21,7 +21,6 @@ end
function GuiElement:initWrapper()
self.scene = core.scenemanager.nextScene or core.scenemanagerself:getCurrent()
self.gui = self.scene.gui
self.assets = self.scene.assets
end
function GuiElement:setKeyPressAction(func)

View file

@ -4,7 +4,7 @@ local TextElement = Parent:extend()
function TextElement:new(name, fontName, text, x, y, align)
TextElement.super.new(self, name, x, y, 1, 1)
self.text = text
self.font = self.assets.fonts[fontName]
self.fontName = fontName
self.align = align
self.opacity = 1
@ -16,7 +16,8 @@ end
function TextElement:draw()
self.font:setColor(1, 1, 1, self.opacity)
self.font:draw(self:getText(), self.x, self.y, -1, self.align)
assets.draw()
assets:printf(self.fontName, self:getText(), self.x, self.y, -1, self.align)
love.graphics.setColor(1, 1, 1, 1)
end

View file

@ -3,7 +3,7 @@ local TileElement = Parent:extend()
function TileElement:new(name, assetName, id, x, y,r,sx,sy,ox,oy, opacity)
self:initWrapper()
local asset = self.assets.tileset[assetName]
local asset = assets.tileset:get(assetName)
assert(asset ~= nil, assetName .. " ( tileset ) doesn't exist")
self.tileId = id

View file

@ -134,13 +134,10 @@ function Gui:addSFX(guiName, sfxName)
self.sfx[guiName] = sfxName
end
function Gui:playSFX(type)
local sfxName = self.sfx[type]
function Gui:playSFX(sfxType)
local sfxName = self.sfx[sfxType]
if (sfxName ~= nil) then
local sfx = self.scene.assets.sfx[sfxName]
if (sfx ~= nil) then
sfx:play()
end
assets:playSFX(self.sfx)
end
end

View file

@ -48,7 +48,6 @@ end
function BaseWidget:initWrapper()
self.scene = core.scenemanager.nextScene or core.scenemanager:getCurrent()
self.gui = self.scene.gui
self.assets = self.scene.assets
end
function BaseWidget:setFunc(func)
@ -64,11 +63,6 @@ function BaseWidget:getScene()
return core.scenemanager.nextScene or core.scenemanager:getCurrent()
end
function BaseWidget:getAssets()
local scene = core.scenemanager.nextScene or core.scenemanager:getCurrent()
return scene.assets
end
function BaseWidget:register()
self.creationID = self.menu:getWidgetNumber()
self.menu:addWidget(self)

View file

@ -27,6 +27,9 @@ local TextWidget = BaseWidget:extend()
-- Simple text widget
function TextWidget:new(menuName, font, label, position, padding)
--assert(font ~= nil, "Font shouldn't be nil")
--assert(font ~= "", "Font shouldn't be empty")
--print(font)
TextWidget.super.new(self, menuName)
self.font = font
self.labels = {}
@ -65,7 +68,7 @@ function TextWidget:setSelectedColor(r, g, b)
end
function TextWidget:getFont()
return self.assets:getFont(self.font)
return self.font
end
function TextWidget:getSelectedColor()
@ -94,7 +97,7 @@ end
function TextWidget:drawCanvas()
local w, h
local font = self:getFont()
local font = assets.fonts:get(self.font)
h = math.floor(self.height / 2) - (font:getHeight() / 2)
for _, complexLabel in pairs(self.labels) do
@ -107,7 +110,7 @@ function TextWidget:drawCanvas()
else
error("Position " .. complexLabel.position .. " is unknown for label " .. complexLabel.label)
end
font:draw(complexLabel.label, w, h, -1, complexLabel.position)
assets:printf(self.font, complexLabel.label, w, h, -1, complexLabel.position)
end
end

View file

@ -27,7 +27,6 @@ function GuiScreen:initWrapper()
self.gui = scene.gui
-- Présent pour la compatibilité
self.controller = self.gui
self.assets = scene.assets
end
function GuiScreen:update(dt)

View file

@ -34,7 +34,7 @@ local BASE_PADDING = 8
function TextMenu:new(name, font, x, y, w, slotNumber, padding, lineSize)
lineSize = lineSize or 1
self:setFont(font)
self.lineHeight = self.font:getHeight() * lineSize
self.lineHeight = assets.fonts:get(font):getHeight() * lineSize
self.name = name
self.padding = padding or BASE_PADDING
@ -66,8 +66,7 @@ function TextMenu:generateSubmenu(pageName, label, parent, list, func, backWidge
end
function TextMenu:setFont(fontName)
local scene = core.scenemanager.nextScene or core.scenemanager:getCurrent()
self.font = scene.assets:getFont(fontName)
self.font = fontName
end
function TextMenu:getFont()

View file

@ -29,7 +29,7 @@ local TextMenuWidget = TextWidget:extend()
function TextMenuWidget:new(menuName, label, position)
local position = position or "left"
TextMenuWidget.super.new(self, menuName, "", label, position, 0)
TextMenuWidget.super.new(self, menuName, "medium", label, position, 0)
end
function TextMenuWidget:getFont()

View file

@ -24,9 +24,10 @@
local Scene = Object:extend()
local Assets = require "framework.scenes.assets"
local Gui = require "framework.scenes.gui"
local AnimatorManager = require "framework.scenes.animators"
-- INIT FUNCTIONS
-- Initialize and configure the scene
@ -34,7 +35,7 @@ function Scene:new()
self.mouse = {}
self.mouse.x, self.mouse.y = core.screen:getMousePosition()
self.assets = Assets()
self.animators = AnimatorManager()
self.sources = core.input:getSources()
self.gui = Gui(self)
@ -66,7 +67,7 @@ end
function Scene:updateScene(dt)
self:updateStart(dt)
self:setKeys()
self.assets:update(dt)
self.animators:update(dt)
self:updateGUI(dt)
self:updateWorld(dt)
self:update(dt)

View file

@ -26,10 +26,11 @@ local Actor2D = require(cwd .. "actor2D")
local GFX = Actor2D:extend()
function GFX:new(world, x, y, spritename)
local width, height = world.scene.assets.sprites[spritename]:getDimensions()
local width, height = world.scene.animators:get(spritename):getDimensions()
GFX.super.new(self, world, "gfx", x - (width/2), y - (height/2), width, height)
self:setSprite(spritename, true)
self.sprite:activateCallbacks()
end
function GFX:animationEnded(animation)

View file

@ -26,7 +26,7 @@ local Actor3D = require(cwd .. "actor3D")
local GFX = Actor3D:extend()
function GFX:new(world, x, y, z, spritename)
local width, height = world.scene.assets.sprites[spritename]:getDimensions()
local width, height = assets.sprites:get(spritename):getDimensions()
GFX.super.new(self, world, "gfx", x - (width/2), y - (width/2), z - (height/2), width, width, height)
self:setSprite(spritename, true)

View file

@ -58,7 +58,6 @@ function BaseActor:setManagers(world)
self.world = world
self.scene = world.scene
self.obj = world.obj
self.assets = self.scene.assets
end
function BaseActor:setDebugColor(r,g,b)

View file

@ -29,8 +29,8 @@ local TexturedBox = Box3D:extend()
function TexturedBox:new(owner, w, h, d, topTexture, bottomTexture)
local bottomTexture = bottomTexture or topTexture
self.topTexture = owner.assets.images[topTexture]
self.bottomTexture = owner.assets.images[bottomTexture]
self.topTexture = assets.texture:get(topTexture)
self.bottomTexture = assets.texture:get(bottomTexture)
TexturedBox.super.new(self, owner, w, h, d)
self.haveLine = false

View file

@ -5,7 +5,7 @@ local Sprite = Object:extend()
function Sprite:new(owner, spritename, ox, oy)
self.owner = owner
self.assets = self.owner.assets
self.animators = self.owner.scene.animators
self.name = spritename or nil
self.ox = ox or 0
self.oy = oy or 0
@ -17,29 +17,34 @@ end
function Sprite:clone()
if self.name ~= nil then
self.spriteClone = self.assets.sprites[self.name]:clone()
self.spriteClone = self.animators:clone(self.name)
end
end
function Sprite:activateCallbacks()
if (self.spriteClone ~= nil) then
self.spriteClone:setCallbackTarget(self.owner)
end
end
function Sprite:isCloned()
return (self.spriteClone == nil)
return (self.spriteClone ~= nil)
end
function Sprite:getAnimator()
if (self:isCloned()) then
return self.spriteClone
else
return self.animators:get(self.name)
end
end
function Sprite:changeAnimation(animation, restart)
if (self:isCloned()) then
self.assets.sprites[self.name]:changeAnimation(animation, restart)
else
self.spriteClone:changeAnimation(animation, restart)
end
self:getAnimator():changeAnimation(animation, restart)
end
function Sprite:setCustomSpeed(customSpeed)
if (self:isCloned()) then
self.assets.sprites[self.name]:setCustomSpeed(customSpeed)
else
self.spriteClone:setCustomSpeed(customSpeed)
end
self:getAnimator():setCustomSpeed(customSpeed)
end
function Sprite:update(dt)
@ -61,11 +66,7 @@ function Sprite:setScallingY(sy)
end
function Sprite:getCurrentAnimation()
if (self:isCloned()) then
return self.assets.sprites[self.name]:getCurrentAnimation()
else
return self.spriteClone:getCurrentAnimation()
end
return self:getAnimator():getCurrentAnimation()
end
@ -74,33 +75,15 @@ function Sprite:getScalling()
end
function Sprite:getFrame()
if (self.name ~= nil) then
if (self.spriteClone ~= nil) then
return self.spriteClone:getFrame()
else
return self.assets.sprites[self.name]:getFrame()
end
end
return self:getAnimator():getAbsoluteFrame()
end
function Sprite:getRelativeFrame()
if (self.name ~= nil) then
if (self.spriteClone ~= nil) then
return self.spriteClone:getRelativeFrame()
else
return self.assets.sprites[self.name]:getRelativeFrame()
end
end
return self:getAnimator().frame
end
function Sprite:getAnimationDuration()
if (self.name ~= nil) then
if (self.spriteClone ~= nil) then
return self.spriteClone:getAnimationDuration()
else
return self.assets.sprites[self.name]:getAnimationDuration()
end
end
return self:getAnimator():getAnimationDuration()
end
function Sprite:draw(x, y, r, sx, sy, ox, oy, kx, ky)
@ -112,7 +95,7 @@ function Sprite:draw(x, y, r, sx, sy, ox, oy, kx, ky)
if (self.spriteClone ~= nil) then
self.spriteClone:draw(x, y, r, sx, sy, ox, oy, kx, ky)
else
self.assets.sprites[self.name]:draw(x, y, r, sx, sy, ox, oy, kx, ky)
self.animators:draw(self.name, x, y, r, sx, sy, ox, oy, kx, ky)
end
end
end