Rebase on Radiance #71
145 changed files with 4561 additions and 2071 deletions
3
.vscode/settings.json
vendored
3
.vscode/settings.json
vendored
|
@ -8,5 +8,8 @@
|
|||
"core",
|
||||
"scenes",
|
||||
"game"
|
||||
],
|
||||
"Lua.diagnostics.disable": [
|
||||
"redundant-parameter"
|
||||
]
|
||||
}
|
||||
|
|
|
@ -7,7 +7,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||
|
||||
## Unreleased
|
||||
|
||||
- Project renamed to Birb
|
||||
- Project renamed to Birb and rebased entirely on Sonic Radiance codebase
|
||||
|
||||
- New loading system
|
||||
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
# Birb Love2D Engine
|
||||
|
||||
Birb aim to be an integrated, simple engine for love2D. It aim to work as a set of managers to automatically handle inputs, screen, and several utilities to make game developpement easier and less repetitive.
|
||||
Birb aim to be an integrated, simple engine for love2D, in replacement of my old "gamecore" love2D engine. It aim to work as a set of managers to automatically handle inputs, screen, and several utilities to make game developpement easier and less repetitive. It's also specialized in game with RPG mechanics, with functions to serialize/deserialize easily datas.
|
||||
|
||||
Birb use [Classic](https://github.com/rxi/classic/) as its base Object.
|
||||
|
||||
## How to load GameCore
|
||||
## How to load Birb
|
||||
|
||||
The birb engine must be located in the `birb/` folder to work. After that, all you have to do is to load a gamecore based engine and then.
|
||||
|
||||
|
|
|
@ -23,19 +23,22 @@
|
|||
|
||||
function love.update(dt)
|
||||
core:update(dt)
|
||||
if (game ~= nil) then
|
||||
game:update(dt)
|
||||
end
|
||||
end
|
||||
|
||||
function love.draw()
|
||||
core:draw()
|
||||
end
|
||||
|
||||
function love.mousemoved(x, y, dx, dy)
|
||||
core:mousemoved(x, y, dx, dy)
|
||||
end
|
||||
-- function love.mousemoved(x, y, dx, dy)
|
||||
-- core:mousemoved(x, y, dx, dy)
|
||||
-- end
|
||||
|
||||
function love.mousepressed( x, y, button, istouch )
|
||||
core:mousepressed(x, y, button, istouch)
|
||||
end
|
||||
-- function love.mousepressed( x, y, button, istouch )
|
||||
-- core:mousepressed(x, y, button, istouch)
|
||||
-- end
|
||||
|
||||
function love.keypressed( key, scancode, isrepeat )
|
||||
core:keypressed( key, scancode, isrepeat )
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
]]
|
||||
|
||||
local Rect = require "birb.objects.2D.rect"
|
||||
local Rect = require "birb.classes.2D.rect"
|
||||
local IndexedRect = Rect:extend()
|
||||
|
||||
function IndexedRect:new(origin, ox, oy, w, h)
|
|
@ -21,7 +21,7 @@
|
|||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
]]
|
||||
|
||||
local Point = require "birb.objects.2D.point"
|
||||
local Point = require "birb.classes.2D.point"
|
||||
local Rect = Point:extend()
|
||||
|
||||
function Rect:new(x, y, w, h)
|
||||
|
@ -67,6 +67,10 @@ function Rect:getRelativeCoordinate(dx, dy)
|
|||
return dx - self.x, dy - self.y
|
||||
end
|
||||
|
||||
function Rect:getDimensions()
|
||||
return self.w, self.h
|
||||
end
|
||||
|
||||
function Rect:drawBox()
|
||||
utils.graphics.box(self.x, self.y, self.w, self.h)
|
||||
end
|
|
@ -21,7 +21,7 @@
|
|||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
]]
|
||||
|
||||
local Point = require "birb.objects.3D.point3D"
|
||||
local Point = require "birb.classes.3D.point3D"
|
||||
local Box = Point:extend()
|
||||
|
||||
function Box:new(x, y, z, w, h, d)
|
||||
|
@ -42,6 +42,7 @@ end
|
|||
|
||||
function Box:getShape()
|
||||
local x, y, z, w, h, d = self:getArea()
|
||||
return x, y-z-d, w, h+d
|
||||
end
|
||||
|
||||
function Box:getCorners()
|
|
@ -23,7 +23,7 @@
|
|||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
]]
|
||||
|
||||
local Rect = require "birb.objects.2D.rect"
|
||||
local Rect = require "birb.classes.2D.rect"
|
||||
local IndexedRect = Rect:extend()
|
||||
|
||||
function IndexedRect:new(origin, ox, oy, oz, w, h, d)
|
121
birb/classes/datapack.lua
Normal file
121
birb/classes/datapack.lua
Normal file
|
@ -0,0 +1,121 @@
|
|||
-- datapack.lua :: a categorized and indexed pack of data. Aim to make easy to get
|
||||
-- the category from an element, without having
|
||||
|
||||
--[[
|
||||
Copyright © 2021 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 DataPack = Object:extend()
|
||||
|
||||
local UNCATEGORIZED = "uncategorized"
|
||||
|
||||
function DataPack:new(foldername, categories, areFiles, subfiles)
|
||||
self.foldername = foldername
|
||||
self.areFiles = (areFiles ~= false)
|
||||
self.subfiles = subfiles or {}
|
||||
self.categories = categories or {}
|
||||
--print("loading " .. foldername)
|
||||
self:loadAllDatas()
|
||||
end
|
||||
|
||||
function DataPack:getBaseDirectory(lua)
|
||||
local foldername = self.foldername
|
||||
if (not lua) then
|
||||
foldername = string.gsub(foldername, "%.", "/")
|
||||
end
|
||||
return utils.datas.concatDataFolder(foldername, lua)
|
||||
end
|
||||
|
||||
function DataPack:getCategoryDirectory(category, lua)
|
||||
if (category == UNCATEGORIZED) then
|
||||
return self:getBaseDirectory(lua)
|
||||
else
|
||||
return utils.datas.concatFolder(self:getBaseDirectory(lua), category, lua)
|
||||
end
|
||||
end
|
||||
|
||||
function DataPack:haveCategories()
|
||||
return (#self.categories > 0)
|
||||
end
|
||||
|
||||
function DataPack:loadAllDatas()
|
||||
self.index = {}
|
||||
self.reverseIndex = {}
|
||||
|
||||
if (self:haveCategories()) then
|
||||
for i, category in ipairs(self.categories) do
|
||||
self:loadDatas(category)
|
||||
end
|
||||
else
|
||||
self:loadDatas(UNCATEGORIZED)
|
||||
end
|
||||
end
|
||||
|
||||
function DataPack:loadDatas(category)
|
||||
local directory = self:getCategoryDirectory(category)
|
||||
local items = love.filesystem.getDirectoryItems(directory)
|
||||
self.reverseIndex[category] = {}
|
||||
for i, filename in ipairs(items) do
|
||||
if (utils.datas.isLuaFile(filename) == self.areFiles) then
|
||||
if (self.areFiles) then
|
||||
filename = utils.datas.luaFileToModule(filename)
|
||||
end
|
||||
|
||||
if (self.index[filename] ~= nil) then
|
||||
error("Data " .. filename .. " already exists for " .. self.foldername)
|
||||
end
|
||||
--print("loading " .. filename .. " from category " .. category .. " for " .. self.foldername)
|
||||
self.index[filename] = category
|
||||
table.insert(self.reverseIndex[category], filename)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function DataPack:dataExists(name)
|
||||
return (self.index[name] ~= nil)
|
||||
end
|
||||
|
||||
function DataPack:getPath(name, lua)
|
||||
if (not self:dataExists(name)) then
|
||||
error("Data " .. name .. " do not exist for " .. self.foldername)
|
||||
end
|
||||
local category = self.index[name]
|
||||
|
||||
local categoryDirectory = self:getCategoryDirectory(category, true)
|
||||
|
||||
return utils.datas.concatFolder(categoryDirectory, name, lua)
|
||||
end
|
||||
|
||||
function DataPack:get(name)
|
||||
local path = self:getPath(name, true)
|
||||
local data = utils.datas.copy(path)
|
||||
if (not self.areFiles) then
|
||||
for i, subfile in ipairs(self.subfiles) do
|
||||
data[subfile] = utils.datas.copyDataset(path, subfile)
|
||||
end
|
||||
end
|
||||
return data
|
||||
end
|
||||
|
||||
function DataPack:getFromCategory(category)
|
||||
return self.reverseIndex[category] or {}
|
||||
end
|
||||
|
||||
return DataPack
|
63
birb/classes/parser.lua
Normal file
63
birb/classes/parser.lua
Normal file
|
@ -0,0 +1,63 @@
|
|||
-- parser.lua :: a data parser, used to parse data from arguments
|
||||
|
||||
--[[
|
||||
Copyright © 2021 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 Parser = Object:extend()
|
||||
|
||||
function Parser:new(headings, argumentsList, argumentwrapper, nullableNbr)
|
||||
self.headings = headings
|
||||
self.argumentsList = argumentsList
|
||||
self.argumentwrapper = argumentwrapper or ""
|
||||
self.nullableNbr = nullableNbr or 0
|
||||
end
|
||||
|
||||
function Parser:getArguments(name)
|
||||
if (self.argumentsList[name] ~= nil) then
|
||||
local arguments = {}
|
||||
utils.table.mergeList(arguments, self.headings)
|
||||
utils.table.mergeList(arguments, self.argumentsList[name])
|
||||
return arguments
|
||||
else
|
||||
error("No arguments data for argumentList " .. name)
|
||||
end
|
||||
end
|
||||
|
||||
function Parser:parse(datas)
|
||||
local arguments = self:getArguments(datas[1])
|
||||
--print(utils.table.toString(arguments))
|
||||
local parsedData = utils.table.parse(datas, arguments, self.nullableNbr)
|
||||
if (utils.string.isEmpty(self.argumentwrapper)) then
|
||||
-- print(utils.table.toString(parsedData))
|
||||
return parsedData
|
||||
else
|
||||
local finalTable = {}
|
||||
for i, heading in ipairs(self.headings) do
|
||||
finalTable[heading] = parsedData[heading]
|
||||
parsedData[heading] = nil
|
||||
end
|
||||
finalTable[self.argumentwrapper] = parsedData
|
||||
-- print(utils.table.toString(finalTable))
|
||||
return finalTable
|
||||
end
|
||||
end
|
||||
|
||||
return Parser
|
115
birb/classes/predicate/init.lua
Normal file
115
birb/classes/predicate/init.lua
Normal file
|
@ -0,0 +1,115 @@
|
|||
-- classes/predicates :: a predicate system, to be an intermediary between condition
|
||||
-- solvers and complex conditions. You simply create a predicate with your data and the
|
||||
-- solver to create a predicate, then use the Predicate:solve() API to get your response
|
||||
|
||||
-- To create a Predicate, prefer the Predicate.createPredicate instead of Predicate:new()
|
||||
-- As it'll allow you to dynamically create simple or complex predicate on the fly
|
||||
-- while Predicate:new() will try to create a complex predicate
|
||||
|
||||
--[[
|
||||
Copyright © 2021 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 Predicate = Object:extend()
|
||||
local SimplePredicate = require "birb.classes.predicate.simple"
|
||||
|
||||
function Predicate.createPredicate(data, solver, asker)
|
||||
local predicate = nil
|
||||
if (type(data) == "table") then
|
||||
predicate = Predicate(data, solver, asker)
|
||||
end
|
||||
if (type(data) == "string") then
|
||||
predicate = SimplePredicate(data, solver, asker)
|
||||
end
|
||||
|
||||
if (predicate ~= nil) then
|
||||
return predicate
|
||||
else
|
||||
error("Predicate data aren't a table or a string : " .. tostring(data))
|
||||
end
|
||||
end
|
||||
|
||||
function Predicate:new(data ,solver, asker)
|
||||
self.solver = solver
|
||||
self.asker = asker
|
||||
self.beginAt = 1
|
||||
self:setType(data)
|
||||
self.notTag = false
|
||||
self:setList(data)
|
||||
end
|
||||
|
||||
function Predicate:solve()
|
||||
local predicateSolved
|
||||
if (self.type == "or") then
|
||||
predicateSolved = self:solveOr()
|
||||
else
|
||||
predicateSolved = self:solveAnd()
|
||||
end
|
||||
|
||||
if (self.notTag) then
|
||||
predicateSolved = (predicateSolved == false)
|
||||
end
|
||||
|
||||
return predicateSolved
|
||||
end
|
||||
|
||||
-- INTERNAL FUNCTIONS
|
||||
-- Handle the complex predicate
|
||||
|
||||
function Predicate:setType(data)
|
||||
self.type = "and"
|
||||
if (type(data[1]) == "string") then
|
||||
if (data[1] == "or") or (data[1] == "and") then
|
||||
self.beginAt = 2
|
||||
self.type = data[1]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function Predicate:setList(data)
|
||||
self.list = {}
|
||||
for i = self.beginAt, #data, 1 do
|
||||
if (i == #data) and (data[i] == "not") then
|
||||
self.notTag = true
|
||||
else
|
||||
table.insert(self.list, Predicate.createPredicate(data[i], self.solver, self.asker))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function Predicate:solveOr()
|
||||
for i, predicate in ipairs(self.list) do
|
||||
if (predicate:solve()) then
|
||||
return true
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
function Predicate:solveAnd()
|
||||
for i, predicate in ipairs(self.list) do
|
||||
if (not predicate:solve()) then
|
||||
return false
|
||||
end
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
return Predicate
|
68
birb/classes/predicate/simple.lua
Normal file
68
birb/classes/predicate/simple.lua
Normal file
|
@ -0,0 +1,68 @@
|
|||
-- classes/simple :: the actual solver of the predicate system. It parse a condition
|
||||
-- system, and pass the data to a solver function. If the last argument of a condition
|
||||
-- is "not", it'll negate the whole condition.
|
||||
|
||||
-- Each solver function will get as argument the list of conditions, the predicate and the
|
||||
-- asker. The predicate contain an utility subclass with some function to handle easily
|
||||
-- some stuff like converting truth tags or comparing numbers
|
||||
-- An empty string will return true, a non-existing solver question an error, except if the solver have a
|
||||
-- default function.
|
||||
|
||||
--[[
|
||||
Copyright © 2021 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 SimplePredicate = Object:extend()
|
||||
local SEPARATOR = ":"
|
||||
local NOT = "not"
|
||||
local DEFAULT = "default"
|
||||
|
||||
SimplePredicate.utils = require "birb.classes.predicate.utils"
|
||||
|
||||
function SimplePredicate:new(data, solver, asker)
|
||||
self.solver = solver
|
||||
self.asker = asker
|
||||
self.data = data
|
||||
end
|
||||
|
||||
function SimplePredicate:solve()
|
||||
if (utils.string.isEmpty(self.data)) then
|
||||
return true
|
||||
end
|
||||
local conditionArgs = utils.string.split(self.data, SEPARATOR)
|
||||
local solverFunction = self:getFunction(conditionArgs[1])
|
||||
local conditionFulfilled = solverFunction(conditionArgs, self, self.asker)
|
||||
if (conditionArgs[#conditionArgs] == NOT) then
|
||||
conditionFulfilled = (not conditionFulfilled)
|
||||
end
|
||||
return conditionFulfilled
|
||||
end
|
||||
|
||||
function SimplePredicate:getFunction(functionName)
|
||||
if (self.solver[functionName] == nil) then
|
||||
if (self.solver[DEFAULT] == nil) then
|
||||
error("Function " .. functionName .. " doesn't exist in solver, and it doesn't have a 'default' function.")
|
||||
end
|
||||
return self.solver[DEFAULT]
|
||||
end
|
||||
return self.solver[functionName]
|
||||
end
|
||||
|
||||
return SimplePredicate
|
|
@ -1,7 +1,7 @@
|
|||
-- timer.lua :: a basic implementation of a timer for the actor system.
|
||||
-- predicate/utils :: Simple utilities for predicates
|
||||
|
||||
--[[
|
||||
Copyright © 2019 Kazhnuz
|
||||
Copyright © 2021 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
|
||||
|
@ -21,25 +21,45 @@
|
|||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
]]
|
||||
|
||||
local Timer = Object:extend()
|
||||
local ConditionsUtils = {}
|
||||
|
||||
function Timer:new(controller, duration, name)
|
||||
self.controller = controller
|
||||
|
||||
self.time = duration
|
||||
self.name = name
|
||||
end
|
||||
|
||||
function Timer:update(dt)
|
||||
self.time = self.time - dt
|
||||
if (self.time <= 0) then
|
||||
self:finish()
|
||||
function ConditionsUtils.testVariables(var1, testType, var2)
|
||||
local var2 = tonumber(var2)
|
||||
if (testType == "eq" and var1 == var2) then
|
||||
return true
|
||||
end
|
||||
if (testType == "ne" and var1 ~= var2) then
|
||||
return true
|
||||
end
|
||||
if (testType == "gt" and var1 > var2) then
|
||||
return true
|
||||
end
|
||||
if (testType == "ge" and var1 >= var2) then
|
||||
return true
|
||||
end
|
||||
if (testType == "lt" and var1 < var2) then
|
||||
return true
|
||||
end
|
||||
if (testType == "le" and var1 <= var2) then
|
||||
return true
|
||||
end
|
||||
|
||||
return false
|
||||
end
|
||||
|
||||
function Timer:finish()
|
||||
self.controller:timerResponse(self.name)
|
||||
self.controller.timers[self.name] = nil
|
||||
function ConditionsUtils.testBool(bool, boolType)
|
||||
return (bool == (boolType == "V"))
|
||||
end
|
||||
|
||||
return Timer
|
||||
function ConditionsUtils.merge(cond)
|
||||
local returnString = ""
|
||||
for i, condElement in ipairs(cond) do
|
||||
returnString = returnString .. condElement
|
||||
if (i < #cond) then
|
||||
returnString = returnString .. ":"
|
||||
end
|
||||
end
|
||||
return returnString
|
||||
end
|
||||
|
||||
return ConditionsUtils;
|
139
birb/classes/serializable/init.lua
Normal file
139
birb/classes/serializable/init.lua
Normal file
|
@ -0,0 +1,139 @@
|
|||
-- classes/serializable :: a serializable object, can give its field as data
|
||||
|
||||
--[[
|
||||
Copyright © 2021 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 Serializable = Object:extend()
|
||||
|
||||
function Serializable:new(serializeFields, listSerializable)
|
||||
self.serializeFields = serializeFields
|
||||
self.listSerializable = listSerializable
|
||||
end
|
||||
|
||||
function Serializable:getData()
|
||||
local data = {}
|
||||
-- We serialize all fields
|
||||
if (self.serializeFields ~= nil) then
|
||||
for _, key in ipairs(self.serializeFields) do
|
||||
data[key] = self:wrapField(key)
|
||||
end
|
||||
end
|
||||
-- We serialize all list of serializable
|
||||
if (self.listSerializable ~= nil) then
|
||||
for _, key in ipairs(self.listSerializable) do
|
||||
data[key] = self:wrapList(key)
|
||||
end
|
||||
end
|
||||
return data
|
||||
end
|
||||
|
||||
function Serializable:wrapField(key)
|
||||
local serializedField = self[key]
|
||||
if (serializedField ~= nil) then
|
||||
if (type(serializedField) == "table" and serializedField.is ~= nil) then
|
||||
if (serializedField:is(Serializable)) then
|
||||
serializedField = serializedField:getData()
|
||||
serializedField.isSerializable = true
|
||||
end
|
||||
end
|
||||
self:print(key, serializedField, false)
|
||||
return serializedField
|
||||
end
|
||||
end
|
||||
|
||||
function Serializable:wrapList(key)
|
||||
local serializedList = {}
|
||||
serializedList.isListSerializable = true
|
||||
for listKey, listElement in pairs(self[key]) do
|
||||
serializedList[listKey] = listElement:getData()
|
||||
end
|
||||
self:print(key, serializedList, false)
|
||||
return serializedList
|
||||
end
|
||||
|
||||
function Serializable:setData(data)
|
||||
for key, value in pairs(data) do
|
||||
if (key ~= "serializedField") then
|
||||
self:unwrapField(key, value)
|
||||
end
|
||||
end
|
||||
self:finishDeserialization()
|
||||
end
|
||||
|
||||
function Serializable:unwrapField(key, value)
|
||||
local serializedField = value
|
||||
if (serializedField ~= nil) then
|
||||
if (type(serializedField) == "table") then
|
||||
if (serializedField.isSerializable == true) then
|
||||
self[key]:setData(serializedField)
|
||||
elseif (serializedField.isListSerializable) then
|
||||
self:unwrapList(key, serializedField)
|
||||
else
|
||||
self[key] = serializedField or self[key]
|
||||
end
|
||||
else
|
||||
self[key] = serializedField or self[key]
|
||||
self:print(key, serializedField, true)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function Serializable:unwrapList(key, list)
|
||||
if (list == nil) then
|
||||
error("List " .. key .. " shouldn't be null in the save")
|
||||
end
|
||||
for listKey, listElement in pairs(list) do
|
||||
if (listKey ~= "isListSerializable") then
|
||||
self[key][listKey]:setData(listElement)
|
||||
end
|
||||
end
|
||||
self:print(key, list, true)
|
||||
end
|
||||
|
||||
function Serializable:print(key, value, isLoading)
|
||||
local loadString = "Loading "
|
||||
if (isLoading == false) then
|
||||
loadString = "Saving "
|
||||
end
|
||||
local valueString = value
|
||||
if type(valueString) == "boolean" then
|
||||
if valueString then
|
||||
valueString = "true"
|
||||
else
|
||||
valueString = "false"
|
||||
end
|
||||
end
|
||||
if (type(value) == "table") then
|
||||
valueString = utils.table.toString(value)
|
||||
end
|
||||
loadString = loadString .. key .. " " .. ": " .. valueString
|
||||
if (core ~= nil) then
|
||||
core.debug:debug("serializable", loadString)
|
||||
else
|
||||
--print("serializable", loadString)
|
||||
end
|
||||
end
|
||||
|
||||
function Serializable:finishDeserialization()
|
||||
-- Empty function callback
|
||||
end
|
||||
|
||||
return Serializable
|
73
birb/classes/serializable/serializer.lua
Normal file
73
birb/classes/serializable/serializer.lua
Normal file
|
@ -0,0 +1,73 @@
|
|||
-- classes/serializable/serializer :: a serializer, able to put stuff into a bin file
|
||||
|
||||
--[[
|
||||
Copyright © 2021 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 Serializable = require "birb.classes.serializable"
|
||||
local Serializer = Serializable:extend()
|
||||
local binser = require("birb.libs.binser")
|
||||
|
||||
function Serializer:new(serializeFields, listSerializable)
|
||||
Serializer.super.new(self, serializeFields, listSerializable)
|
||||
end
|
||||
|
||||
function Serializer:reset()
|
||||
|
||||
end
|
||||
|
||||
function Serializer:delete(filename)
|
||||
local filepath = self:getFile(true, filename)
|
||||
if utils.filesystem.exists(filename) then
|
||||
love.filesystem.remove(filepath)
|
||||
end
|
||||
end
|
||||
|
||||
function Serializer:deserialize(filename)
|
||||
local filepath = self:getFile(true, filename)
|
||||
if utils.filesystem.exists(filename) then
|
||||
local loadedDatas = binser.readFile(filepath)
|
||||
self:setData(loadedDatas[1])
|
||||
else
|
||||
self:reset()
|
||||
end
|
||||
end
|
||||
|
||||
function Serializer:serialize(filename)
|
||||
local data = self:getData()
|
||||
|
||||
local filepath = self:getFile(true, filename)
|
||||
binser.writeFile(filepath, data)
|
||||
end
|
||||
|
||||
function Serializer:getFile(absolute, filename)
|
||||
local dir = ""
|
||||
if absolute then
|
||||
dir = love.filesystem.getSaveDirectory() .. "/"
|
||||
if (not utils.filesystem.exists(dir)) then
|
||||
love.filesystem.createDirectory("")
|
||||
end
|
||||
end
|
||||
|
||||
local filepath = dir .. filename
|
||||
|
||||
return filepath
|
||||
end
|
||||
|
||||
return Serializer
|
14
birb/classes/time/func.lua
Normal file
14
birb/classes/time/func.lua
Normal file
|
@ -0,0 +1,14 @@
|
|||
local Timer = require "birb.classes.time.timer"
|
||||
local TimedFunction = Timer:extend()
|
||||
|
||||
function TimedFunction:new(actor, name, func, t)
|
||||
TimedFunction.super.new(self, actor, name, t)
|
||||
self.func = func
|
||||
end
|
||||
|
||||
function TimedFunction:finish()
|
||||
self.actor.funcs[self.name] = nil
|
||||
self.func()
|
||||
end
|
||||
|
||||
return TimedFunction
|
|
@ -1,4 +1,6 @@
|
|||
-- timers :: a basic implementation of a timer system.
|
||||
|
||||
-- time.lua :: a timer, tweener and timed switch handler.
|
||||
-- This class need birb.libs.tween to work
|
||||
|
||||
--[[
|
||||
Copyright © 2019 Kazhnuz
|
||||
|
@ -21,57 +23,102 @@
|
|||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
]]
|
||||
|
||||
local cwd = (...):gsub('%.init$', '') .. "."
|
||||
local TweenManager = Object:extend()
|
||||
|
||||
local TimersManager = Object:extend()
|
||||
local Timer = require(cwd .. "libs.timer")
|
||||
local Tween = require(cwd .. "libs.tween")
|
||||
local tween = require "birb.libs.tween"
|
||||
local Timer = require "birb.classes.time.timer"
|
||||
local TimedFunction = require "birb.classes.time.func"
|
||||
|
||||
|
||||
function TimersManager:new(subject)
|
||||
function TweenManager:new(subject)
|
||||
self.subject = subject
|
||||
self.time = 0
|
||||
|
||||
self.timers = {}
|
||||
self.switches = {}
|
||||
self.tweens = {}
|
||||
self.switches = {}
|
||||
|
||||
self.timers = {}
|
||||
self.funcs = {}
|
||||
end
|
||||
|
||||
-- UPDATE
|
||||
-- Update every timers
|
||||
function TweenManager:newTween(start, duration, target, easing)
|
||||
table.insert(self.tweens, self:createTween(start, duration, target, easing))
|
||||
end
|
||||
|
||||
function TimersManager:update(dt)
|
||||
self.time = self.time + dt
|
||||
function TweenManager:setNamedTween(name, start, duration, target, easing)
|
||||
self.tweens[name] = nil
|
||||
self.tweens[name] = self:createTween(start, duration, target, easing)
|
||||
end
|
||||
|
||||
for k, timer in pairs(self.timers) do
|
||||
timer:update(dt)
|
||||
end
|
||||
function TweenManager:createTween(start, duration, target, easing)
|
||||
local newTween = {}
|
||||
-- we add the data into a tween wrapper
|
||||
newTween.tween = tween.new(duration, self.subject, target, easing)
|
||||
newTween.start = self.time + start -- /!\ START IS RELATIVE TO CURRENT TIME
|
||||
newTween.clear = newTween.start + duration
|
||||
|
||||
self:updateSwitches(dt)
|
||||
self:updateTweens(dt)
|
||||
return newTween
|
||||
end
|
||||
|
||||
function TweenManager:removeNamedTween(name)
|
||||
self.tweens[name] = nil
|
||||
end
|
||||
|
||||
function TweenManager:haveTween()
|
||||
return #self.tweens > 0
|
||||
end
|
||||
|
||||
-- TIMER FUNCTIONS
|
||||
-- Handle the timers
|
||||
-- Help to get info from timers
|
||||
|
||||
function TimersManager:newTimer(duration, name)
|
||||
self.timers[name] = Timer(self, duration, name)
|
||||
function TweenManager:newTimer(start, name)
|
||||
self.timers[name] = Timer(self, name, start)
|
||||
end
|
||||
|
||||
function TimersManager:timerResponse(timername)
|
||||
if self.subject.timerResponse == nil then
|
||||
core.debug:logWarn("TimersManager", "the subject have no timerResponse function")
|
||||
return 0
|
||||
function TweenManager:delayTimer(time, name, absolute)
|
||||
if (self.timers[name] ~= nil) then
|
||||
self.timers[name]:delay(time, absolute)
|
||||
end
|
||||
self.subject:timerResponse(timername)
|
||||
end
|
||||
|
||||
function TweenManager:getTimerInfo(name)
|
||||
if (self.timers[name] ~= nil) then
|
||||
return self.timers[name]:getInfo()
|
||||
end
|
||||
end
|
||||
|
||||
function TweenManager:removeTimer(name)
|
||||
self.timers[name] = nil
|
||||
end
|
||||
|
||||
-- FUNCTION FUNCTIONS
|
||||
-- Help to get functions
|
||||
|
||||
function TweenManager:newFunc(start, name, func)
|
||||
self.funcs[name] = TimedFunction(self, name, func, start)
|
||||
end
|
||||
|
||||
function TweenManager:delayFunc(time, name, absolute)
|
||||
if (self.funcs[name] ~= nil) then
|
||||
self.funcs[name]:delay(time, absolute)
|
||||
end
|
||||
end
|
||||
|
||||
function TweenManager:getFuncInfo(name)
|
||||
if (self.funcs[name] ~= nil) then
|
||||
return self.funcs[name]:getInfo()
|
||||
end
|
||||
end
|
||||
|
||||
function TweenManager:removeFunc(name)
|
||||
self.funcs[name] = nil
|
||||
end
|
||||
|
||||
-- SWITCH FUNCTIONS
|
||||
-- Handle switches
|
||||
-- Help to handle switches
|
||||
|
||||
function TimersManager:newSwitch(start, bools)
|
||||
function TweenManager:newSwitch(start, bools)
|
||||
local newSwitch = {}
|
||||
-- we add the data into a switch wrapper
|
||||
-- we add the data into a tween wrapper
|
||||
newSwitch.bools = bools
|
||||
newSwitch.start = self.time + start -- /!\ START IS RELATIVE TO CURRENT TIME
|
||||
newSwitch.clear = newSwitch.start + 1
|
||||
|
@ -79,8 +126,19 @@ function TimersManager:newSwitch(start, bools)
|
|||
table.insert(self.switches, newSwitch)
|
||||
end
|
||||
|
||||
function TimersManager:updateSwitches(dt)
|
||||
for i, switch in ipairs(self.switches) do
|
||||
function TweenManager:update(dt)
|
||||
self.time = self.time + dt
|
||||
|
||||
for key, tweenWrapper in pairs(self.tweens) do
|
||||
if (self.time > tweenWrapper.start) then
|
||||
tweenWrapper.tween:update(dt)
|
||||
if (self.time > tweenWrapper.clear) then
|
||||
self.tweens[key] = nil
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
for i, switch in pairs(self.switches) do
|
||||
if (self.time > switch.start) then
|
||||
-- We test each boolean in the switch
|
||||
for i, bool in ipairs(switch.bools) do
|
||||
|
@ -95,32 +153,27 @@ function TimersManager:updateSwitches(dt)
|
|||
table.remove(self.switches, i)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- TWEENING FUNCTIONS
|
||||
-- Handle tween support via tween.lua
|
||||
|
||||
function TimersManager:newTween(start, duration, target, easing)
|
||||
local newTween = {}
|
||||
-- we add the data into a tween wrapper
|
||||
newTween.tween = Tween.new(duration, self.subject, target, easing)
|
||||
newTween.start = self.time + start -- /!\ START IS RELATIVE TO CURRENT TIME
|
||||
newTween.clear = newTween.start + duration
|
||||
|
||||
table.insert(self.tweens, newTween)
|
||||
end
|
||||
|
||||
function TimersManager:updateTweens(dt)
|
||||
for i, tweenWrapper in ipairs(self.tweens) do
|
||||
if (self.time > tweenWrapper.start) then
|
||||
tweenWrapper.tween:update(dt)
|
||||
for k, timer in pairs(self.timers) do
|
||||
timer:update(dt)
|
||||
end
|
||||
|
||||
for k, func in pairs(self.funcs) do
|
||||
func:update(dt)
|
||||
end
|
||||
|
||||
self:clearEndedTweens()
|
||||
end
|
||||
|
||||
function TimersManager:clearEndedTweens()
|
||||
function TweenManager:timerResponse(timername)
|
||||
if self.subject.timerResponse == nil then
|
||||
core.debug:warning("tweenmanager", "the subject have no timerResponse function")
|
||||
return 0
|
||||
end
|
||||
self.subject:timerResponse(timername)
|
||||
end
|
||||
|
||||
function TweenManager:clearEndedTweens(dt)
|
||||
for i, tweenWrapper in ipairs(self.tweens) do
|
||||
if (self.time > tweenWrapper.clear) then
|
||||
table.remove(self.tweens, i)
|
||||
|
@ -128,4 +181,4 @@ function TimersManager:clearEndedTweens()
|
|||
end
|
||||
end
|
||||
|
||||
return TimersManager
|
||||
return TweenManager
|
|
@ -24,6 +24,7 @@
|
|||
local Timer = Object:extend()
|
||||
|
||||
function Timer:new(actor, name, t)
|
||||
self.baseTime = t
|
||||
self.time = t
|
||||
self.actor = actor
|
||||
self.name = name
|
||||
|
@ -36,9 +37,23 @@ function Timer:update(dt)
|
|||
end
|
||||
end
|
||||
|
||||
function Timer:delay(time, absolute)
|
||||
if (absolute == true) then
|
||||
self.baseTime = self.baseTime + (time - self.time)
|
||||
self.time = time
|
||||
else
|
||||
self.baseTime = self.baseTime + time
|
||||
self.time = self.time + time
|
||||
end
|
||||
end
|
||||
|
||||
function Timer:getInfo()
|
||||
return self.time, self.baseTime, (self.time / self.baseTime)
|
||||
end
|
||||
|
||||
function Timer:finish()
|
||||
self.actor:timerResponse(self.name)
|
||||
self.actor.timers[self.name] = nil
|
||||
self.actor:timerResponse(self.name)
|
||||
end
|
||||
|
||||
return Timer
|
|
@ -1,105 +0,0 @@
|
|||
-- core/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 AssetManager = Object:extend()
|
||||
|
||||
function AssetManager:new()
|
||||
self.locals = {}
|
||||
self.globals = {}
|
||||
self.updatables = {}
|
||||
|
||||
self.isActive = true
|
||||
end
|
||||
|
||||
function AssetManager:update(dt)
|
||||
if (self.isActive) then
|
||||
for key, updatable in pairs(self.updatables) do
|
||||
updatable:update(dt)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function AssetManager:add(name, asset, isGlobal)
|
||||
if (isGlobal == true) then
|
||||
self:addGlobal(name, asset)
|
||||
else
|
||||
self:addLocal(name, asset)
|
||||
end
|
||||
end
|
||||
|
||||
function AssetManager:addGlobal(name, asset)
|
||||
self.globals[name] = asset
|
||||
end
|
||||
|
||||
function AssetManager:addLocal(name, asset)
|
||||
self.locals[name] = asset
|
||||
end
|
||||
|
||||
function AssetManager:clear()
|
||||
self.locals = {}
|
||||
self.globals = {}
|
||||
collectgarbage()
|
||||
end
|
||||
|
||||
function AssetManager:clearLocal()
|
||||
self.locals = {}
|
||||
end
|
||||
|
||||
function AssetManager:get(name)
|
||||
local asset
|
||||
if self.locals[name] ~= nil then
|
||||
asset = self.locals[name]
|
||||
else
|
||||
asset = self.globals[name]
|
||||
end
|
||||
|
||||
if (asset ~= nil) then
|
||||
return asset
|
||||
else
|
||||
core.debug:fail("core.assets", "L'asset " .. name .. " n'existe pas.")
|
||||
end
|
||||
end
|
||||
|
||||
-- Specific functions
|
||||
|
||||
function AssetManager:playSFX(name)
|
||||
local asset = self:get(name)
|
||||
asset:play()
|
||||
end
|
||||
|
||||
-- Activity Functions
|
||||
|
||||
function AssetManager:setActivity(isActive)
|
||||
self.isActive = isActive
|
||||
end
|
||||
|
||||
function AssetManager:switchActivity()
|
||||
self.isActive = (self.isActive == false)
|
||||
end
|
||||
|
||||
function AssetManager:getActivity()
|
||||
return self.isActive
|
||||
end
|
||||
|
||||
return AssetManager
|
82
birb/core/datas.lua
Normal file
82
birb/core/datas.lua
Normal file
|
@ -0,0 +1,82 @@
|
|||
-- datas.lua :: The main file of the core system, an object full of subsystem
|
||||
-- loaded by the game to handle the main functions (like screen, translation,
|
||||
-- inputs…)
|
||||
|
||||
--[[
|
||||
Copyright © 2021 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 DataManager = Object:extend()
|
||||
local DataPack = require "birb.classes.datapack"
|
||||
local Parser = require "birb.classes.parser"
|
||||
local index = require "datas.gamedata.index"
|
||||
|
||||
function DataManager:new(core)
|
||||
self.core = core
|
||||
self:loadDatas()
|
||||
self:loadParsers()
|
||||
end
|
||||
|
||||
function DataManager:loadDatas()
|
||||
self.datapacks = {}
|
||||
if (index.datapack ~= nil) then
|
||||
for key, datas in pairs(index.datapacks) do
|
||||
self.core.debug:debug("datamanager", "loading data for " .. key)
|
||||
self.datapacks[key] = DataPack(datas[1], datas[2], datas[3], datas[4], datas[5])
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function DataManager:get(datapack, name)
|
||||
return self.datapacks[datapack]:get(name)
|
||||
end
|
||||
|
||||
function DataManager:exists(datapack, name)
|
||||
return self.datapacks[datapack]:dataExists(name)
|
||||
end
|
||||
|
||||
function DataManager:getFromCategory(datapack, category)
|
||||
return self.datapacks[datapack]:getFromCategory(category)
|
||||
end
|
||||
|
||||
function DataManager:getCategories(datapack)
|
||||
return self.datapacks[datapack].categories
|
||||
end
|
||||
|
||||
-- Load parsers
|
||||
|
||||
function DataManager:loadParsers()
|
||||
self.parsers = {}
|
||||
local items = love.filesystem.getDirectoryItems("datas/parsers")
|
||||
for i, item in ipairs(items) do
|
||||
local filename = utils.datas.luaFileToModule(item)
|
||||
local data = require("datas.parsers." .. filename)
|
||||
|
||||
self.core.debug:debug("datamanager", "creating parser for " .. filename)
|
||||
self.parsers[filename] = Parser(data.headings, data.argumentLists, data.argumentWrapper, 0)
|
||||
end
|
||||
end
|
||||
|
||||
function DataManager:parse(parser, data)
|
||||
return self.parsers[parser]:parse(data)
|
||||
end
|
||||
|
||||
|
||||
return DataManager
|
|
@ -1,4 +1,4 @@
|
|||
-- core/debug.lua :: A basic framework for debug.
|
||||
-- core/debug.lua :: The basic internal debug framework of the birb engine.
|
||||
|
||||
--[[
|
||||
Copyright © 2019 Kazhnuz
|
||||
|
@ -23,128 +23,70 @@
|
|||
|
||||
local DebugSystem = Object:extend()
|
||||
|
||||
local lovebird = require("birb.libs.lovebird")
|
||||
local lovebird
|
||||
|
||||
local ERROR = 0
|
||||
local WARN = 1
|
||||
local INFO = 2
|
||||
local DEBUG = 3
|
||||
local Levels = enum {
|
||||
"ERROR",
|
||||
"WARNING",
|
||||
"INFO",
|
||||
"DEBUG"
|
||||
}
|
||||
|
||||
--- Create a new DebugSystem.
|
||||
-- It allow you to determinate the debug level of the game.
|
||||
-- @param controller the birb core
|
||||
-- @param debugLevel the debug mode level
|
||||
function DebugSystem:new(controller, debugLevel)
|
||||
self.core = controller
|
||||
self.debugLevel = debugLevel or 0
|
||||
self.controller = controller
|
||||
|
||||
self:updateUI()
|
||||
end
|
||||
|
||||
--- Update the DebugSystem.
|
||||
-- @param dt the delta time
|
||||
function DebugSystem:update(dt)
|
||||
self:updateUI(dt)
|
||||
end
|
||||
|
||||
--- Update the lovebird UI if the debug level is debug.
|
||||
-- @param dt the delta time
|
||||
function DebugSystem:updateUI(dt)
|
||||
if (self:isDebug()) then
|
||||
lovebird.update(dt)
|
||||
self.debugLevel = debugLevel or Levels.WARNING
|
||||
self.active = (self.debugLevel == Levels.DEBUG)
|
||||
if (self.active) then
|
||||
lovebird = require "birb.libs.lovebird"
|
||||
lovebird.update()
|
||||
end
|
||||
end
|
||||
|
||||
-- TEST FUNCTIONS
|
||||
-- Simple warper to get easily the debug level
|
||||
|
||||
--- Test if debug level is "DEBUG"
|
||||
-- @return true if the debug level is "DEBUG"
|
||||
function DebugSystem:isDebug()
|
||||
return (self.debugLevel >= DEBUG)
|
||||
end
|
||||
|
||||
--- Test if debug level is "INFO"
|
||||
-- @return true if the debug level is "INFO"
|
||||
function DebugSystem:isInfo()
|
||||
return (self.debugLevel >= INFO)
|
||||
end
|
||||
|
||||
--- Test if debug level is "WARN"
|
||||
-- @return true if the debug level is "WARN"
|
||||
function DebugSystem:isWarn()
|
||||
return (self.debugLevel >= WARN)
|
||||
end
|
||||
|
||||
--- Test if debug level is "ERROR"
|
||||
-- @return true if the debug level is "ERROR"
|
||||
function DebugSystem:isError()
|
||||
return (self.debugLevel >= ERROR)
|
||||
function DebugSystem:update(dt)
|
||||
if (self.active and lovebird ~= nil) then
|
||||
lovebird.update(dt)
|
||||
end
|
||||
end
|
||||
|
||||
-- PRINT FUNCTIONS
|
||||
-- Print and log debug string
|
||||
|
||||
--- Log a debug line
|
||||
--
|
||||
-- @param context the context of the log
|
||||
-- @param string the logged string
|
||||
function DebugSystem:logDebug(context, string)
|
||||
if (self:isDebug()) then
|
||||
print(self:createLogLine("DEBUG", context, string))
|
||||
function DebugSystem:debug(context, string)
|
||||
self:log(Levels.DEBUG, context, string)
|
||||
end
|
||||
|
||||
function DebugSystem:print(context, string)
|
||||
self:log(Levels.INFO, context, string)
|
||||
end
|
||||
|
||||
function DebugSystem:warning(context, string)
|
||||
self:log(Levels.WARNING, context, string)
|
||||
end
|
||||
|
||||
function DebugSystem:error(context, string)
|
||||
self:log(Levels.ERROR, context, string)
|
||||
error(self:getMessage(": ", context, string))
|
||||
end
|
||||
|
||||
function DebugSystem:log(level, context, string)
|
||||
if (self.debugLevel >= level) then
|
||||
print(self:getLogLine(Levels[level], context, string))
|
||||
end
|
||||
end
|
||||
|
||||
--- Log an info
|
||||
--
|
||||
-- @param context the context of the log
|
||||
-- @param string the logged string
|
||||
function DebugSystem:logInfo(context, string)
|
||||
if (self:isInfo()) then
|
||||
print(self:createLogLine("INFO", context, string))
|
||||
function DebugSystem:getLogLine(type, context, string)
|
||||
local head = self.controller:getIdentity(false) .. "|" .. os.date("%x-%X") .. "|" .. type .. "|"
|
||||
return head .. self:getMessage("|", context, string)
|
||||
end
|
||||
|
||||
function DebugSystem:getMessage(separator, string1, string2)
|
||||
if (string2 == nil) then
|
||||
return string1
|
||||
else
|
||||
return string1 .. separator .. string2
|
||||
end
|
||||
end
|
||||
|
||||
--- Log a warning
|
||||
--
|
||||
-- @param context the context of the log
|
||||
-- @param string the logged string
|
||||
function DebugSystem:logWarn(context, string)
|
||||
if (self:isWarn()) then
|
||||
print(self:createLogLine("WARNING", context, string))
|
||||
end
|
||||
end
|
||||
|
||||
--- Log an error
|
||||
--
|
||||
-- @param context the context of the log
|
||||
-- @param string the logged string
|
||||
function DebugSystem:logError(context, string)
|
||||
if (self:isError()) then
|
||||
print(self:createLogLine("ERROR", context, string))
|
||||
end
|
||||
end
|
||||
|
||||
--- Log an error and fail
|
||||
--
|
||||
-- @param context the context of the log
|
||||
-- @param string the logged string
|
||||
function DebugSystem:fail(context, string)
|
||||
if (self:isError()) then
|
||||
print(self:createLogLine("ERROR", context, string))
|
||||
error(string)
|
||||
end
|
||||
end
|
||||
|
||||
--- Create a formatted debug line
|
||||
--
|
||||
-- @param level the level of the log
|
||||
-- @param context the context of the log
|
||||
-- @param string the logged string
|
||||
-- @return the debug line
|
||||
function DebugSystem:createLogLine(level, context, string)
|
||||
local head = self.core:getName() .. "|" .. os.date("%x-%X") .. "|"
|
||||
return head .. level .. "|" .. context .. ": " .. string;
|
||||
end
|
||||
|
||||
return DebugSystem
|
||||
|
|
|
@ -28,33 +28,37 @@ local cwd = (...):gsub('%.init$', '') .. "."
|
|||
local CoreSystem = Object:extend()
|
||||
|
||||
local DebugSystem = require(cwd .. "debug")
|
||||
|
||||
local Options = require(cwd .. "options")
|
||||
local Input = require(cwd .. "input")
|
||||
local Screen = require(cwd .. "screen")
|
||||
local Lang = require(cwd .. "lang")
|
||||
local SceneManager = require(cwd .. "scenemanager")
|
||||
local MusicManager = require(cwd .. "music")
|
||||
local Assets = require(cwd .. "assets")
|
||||
local DataManager = require(cwd .. "datas")
|
||||
|
||||
-- INIT FUNCTIONS
|
||||
-- Initialize and configure the core object
|
||||
|
||||
function CoreSystem:new(debugLevel)
|
||||
local conf = self:getDefaultConf()
|
||||
self.gameName = conf.identity
|
||||
function CoreSystem:new(args)
|
||||
self.args = args
|
||||
self:setDefaultConf()
|
||||
|
||||
self.modules = birb.modules
|
||||
|
||||
self.debug = DebugSystem(self, debugLevel)
|
||||
self.debug = DebugSystem(self, self:getArg("DEBUGLEVEL", true))
|
||||
self.options = Options(self)
|
||||
self.input = Input(self)
|
||||
self.screen = Screen(self)
|
||||
self.scenemanager = SceneManager(self)
|
||||
self.lang = Lang(self)
|
||||
self.music = MusicManager(self)
|
||||
self.assets = Assets(self)
|
||||
self.datas = DataManager(self)
|
||||
end
|
||||
|
||||
self.debug:logDebug("birbcore","Birb initialized")
|
||||
function CoreSystem:setDefaultConf()
|
||||
self.conf = {}
|
||||
self.conf.window = {}
|
||||
self.conf.modules = {}
|
||||
love.conf(self.conf)
|
||||
end
|
||||
|
||||
function CoreSystem:registerGameSystem(gamesystem)
|
||||
|
@ -62,17 +66,29 @@ function CoreSystem:registerGameSystem(gamesystem)
|
|||
end
|
||||
|
||||
function CoreSystem:getDefaultConf()
|
||||
local defaultConf = {}
|
||||
defaultConf.window = {}
|
||||
defaultConf.modules = {}
|
||||
|
||||
love.conf(defaultConf)
|
||||
|
||||
return defaultConf
|
||||
return self.conf
|
||||
end
|
||||
|
||||
function CoreSystem:getName()
|
||||
return self.gameName
|
||||
function CoreSystem:getIdentity(versionned)
|
||||
local identity = self.conf.identity or "birbengine"
|
||||
if (versionned) then
|
||||
local version = self.conf.gameversion or 0
|
||||
identity = identity .. "-" .. version
|
||||
end
|
||||
return identity
|
||||
end
|
||||
|
||||
function CoreSystem:getArg(name, isNumber)
|
||||
for _, arg in ipairs(self.args) do
|
||||
local argData = utils.string.split(arg, "=")
|
||||
if (argData[1] == name) then
|
||||
if (isNumber == true) then
|
||||
return tonumber(argData[2])
|
||||
else
|
||||
return argData[2]
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- MOUSE FUNCTIONS
|
||||
|
@ -104,25 +120,26 @@ end
|
|||
-- Load every sytem every update functions of the scene and objects
|
||||
|
||||
function CoreSystem:update(dt)
|
||||
-- If the frameskip is to high, prefer slowdown to frameskip
|
||||
local dt = math.min(dt, 1/15)
|
||||
self.debug:update(dt)
|
||||
self.input:update(dt)
|
||||
self.screen:update(dt)
|
||||
self.music:update(dt)
|
||||
self.assets:update(dt)
|
||||
|
||||
if (self.game ~= nil) then
|
||||
self.game:update(dt)
|
||||
end
|
||||
|
||||
self.scenemanager:update(dt)
|
||||
self.screen:update(dt)
|
||||
self.music:update(dt)
|
||||
end
|
||||
|
||||
-- DRAW FUNCTIONS
|
||||
-- Draw the whole game
|
||||
|
||||
function CoreSystem:draw()
|
||||
self.scenemanager:redraw()
|
||||
self.scenemanager:draw()
|
||||
self.screen:drawFade()
|
||||
end
|
||||
|
||||
-- EXIT FUNCTIONS
|
||||
|
|
|
@ -143,7 +143,7 @@ function VirtualPad:isDown(key)
|
|||
isdown = love.keyboard.isDown(self.data.keys[key])
|
||||
else
|
||||
local warnstring = "unsupported input device " .. self.type .. " for source " .. self.id
|
||||
core.debug:logWarn("core/input", warnstring)
|
||||
core.debug:warning("core/input", warnstring)
|
||||
end
|
||||
|
||||
return isdown
|
||||
|
@ -159,13 +159,13 @@ function VirtualPad:checkKey(key)
|
|||
local isDown = self:isDown(key)
|
||||
if (isDown) then
|
||||
if not (self.keys[key].isDown) then
|
||||
core.debug:logDebug("virtualpad", "key " .. key .. " is Pressed")
|
||||
--core.debug:print("virtualpad", "key " .. key .. " is Pressed")
|
||||
self.keys[key].isDown = true
|
||||
self.keys[key].isPressed = true
|
||||
self.keys[key].isReleased = false
|
||||
else
|
||||
if (self.keys[key].isPressed) then
|
||||
core.debug:logDebug("virtualpad", "key " .. key .. " is Down")
|
||||
--core.debug:print("virtualpad", "key " .. key .. " is Down")
|
||||
self.keys[key].isPressed = false
|
||||
end
|
||||
end
|
||||
|
@ -176,7 +176,7 @@ function VirtualPad:checkKey(key)
|
|||
self.keys[key].isReleased = true
|
||||
else
|
||||
if (self.keys[key].isReleased) then
|
||||
core.debug:logDebug("virtualpad", "key " .. key .. " is Released")
|
||||
--core.debug:print("virtualpad", "key " .. key .. " is Released")
|
||||
self.keys[key].isReleased = false
|
||||
end
|
||||
end
|
||||
|
|
|
@ -95,7 +95,7 @@ function LanguageManager:getTranslationStringList(lang, library)
|
|||
if fileinfo ~= nil then
|
||||
list = require(_path)
|
||||
else
|
||||
core.debug:logWarn("core/lang","file " .. _path .. " do not exists")
|
||||
core.debug:warning("core/lang","file " .. _path .. " do not exists")
|
||||
end
|
||||
|
||||
return list
|
||||
|
@ -120,7 +120,7 @@ function LanguageManager:translate(library, string)
|
|||
|
||||
if (translation == nil) then
|
||||
translation = string
|
||||
core.debug:logWarn("core/lang", "no translation path found for " .. string .. " in " .. library)
|
||||
core.debug:warning("core/lang", "no translation path found for " .. string .. " in " .. library)
|
||||
end
|
||||
|
||||
return translation
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
-- core/langs.lua :: A music system, in order to add some usefull features
|
||||
-- core/music.lua :: A music system, in order to add some usefull features
|
||||
-- and to make music not scene dependant
|
||||
|
||||
--[[
|
||||
|
@ -54,10 +54,6 @@ function MusicManager:haveMusic()
|
|||
return (self.musics[1] ~= nil)
|
||||
end
|
||||
|
||||
function MusicManager:applyVolume()
|
||||
self.musics[1]:setVolume(self.core.options.data.audio.music / 100)
|
||||
end
|
||||
|
||||
function MusicManager:playMusic()
|
||||
if (self:haveMusic()) then
|
||||
self.musics[1]:setVolume(self.core.options.data.audio.music / 100)
|
||||
|
@ -87,7 +83,7 @@ function MusicManager:silence()
|
|||
end
|
||||
end
|
||||
|
||||
function MusicManager:skipMusic()
|
||||
function MusicManager:skip()
|
||||
if (self:haveMusic()) then
|
||||
self.musics[1]:stop()
|
||||
self.isPlaying = false
|
||||
|
|
|
@ -21,34 +21,36 @@
|
|||
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 OptionsManager = Object:extend()
|
||||
|
||||
local binser = require("birb.libs.binser")
|
||||
local Serializer = require "birb.classes.serializable.serializer"
|
||||
local OptionsManager = Serializer:extend()
|
||||
|
||||
local TRANSLATION_PATH = "datas/languages/"
|
||||
|
||||
local OPTION_FILE = "options.data"
|
||||
|
||||
-- INIT FUNCTIONS
|
||||
-- Initialize and configure the game options
|
||||
|
||||
function OptionsManager:new(core)
|
||||
self.core = core
|
||||
function OptionsManager:new(controller)
|
||||
OptionsManager.super.new(self, {"data"})
|
||||
|
||||
self.controller = controller
|
||||
-- We begin by creating an empty data table before reading the data.
|
||||
self.data = {}
|
||||
self:reset()
|
||||
self:read()
|
||||
end
|
||||
|
||||
function OptionsManager:reset()
|
||||
-- load the default set of config
|
||||
local defaultConf = self.core:getDefaultConf()
|
||||
|
||||
local conf = self.controller:getDefaultConf()
|
||||
-- Reset the option to the game defaults.
|
||||
self.data = {}
|
||||
|
||||
self.data.video = {}
|
||||
self.data.video.crtfilter = false
|
||||
self.data.video.resolution = defaultConf.window.resolution
|
||||
self.data.video.borderless = defaultConf.window.borderless
|
||||
self.data.video.vsync = defaultConf.window.vsync
|
||||
self.data.video.fullscreen = defaultConf.window.fullscreen
|
||||
self.data.video.crtfilter = (conf.window.crtfilter == true)
|
||||
self.data.video.resolution = conf.window.resolution or 1
|
||||
self.data.video.border = (conf.window.borderless == false)
|
||||
self.data.video.vsync = (conf.window.vsync ~= false)
|
||||
self.data.video.fullscreen = (conf.window.fullscreen == true)
|
||||
|
||||
-- We load the default files
|
||||
self.data.input = self:getInputDefaultData()
|
||||
|
@ -57,27 +59,13 @@ function OptionsManager:reset()
|
|||
self.data.language = self:getTranslationDefaultData()
|
||||
|
||||
self.data.audio = {}
|
||||
self.data.audio.music = defaultConf.volume.music
|
||||
self.data.audio.sfx = defaultConf.volume.sfx
|
||||
self.data.audio.music = conf.volume.music or 100
|
||||
self.data.audio.sfx = conf.volume.sfx or 100
|
||||
end
|
||||
|
||||
-- INFO FUNCTIONS
|
||||
-- Get informations from the option managers
|
||||
|
||||
function OptionsManager:getFile(absolute)
|
||||
local dir = ""
|
||||
if absolute then
|
||||
dir = love.filesystem.getSaveDirectory() .. "/"
|
||||
if not utils.filesystem.exists(dir) then
|
||||
love.filesystem.createDirectory( "" )
|
||||
end
|
||||
end
|
||||
|
||||
local filepath = dir .. "options.data"
|
||||
|
||||
return filepath
|
||||
end
|
||||
|
||||
function OptionsManager:getInputDefaultData()
|
||||
local _path = "datas/inputs.lua"
|
||||
local datas = {}
|
||||
|
@ -121,8 +109,7 @@ function OptionsManager:getTranslationDefaultData()
|
|||
local _path = TRANSLATION_PATH .. "init.lua"
|
||||
local fileinfo = love.filesystem.getInfo(_path)
|
||||
local datas = nil
|
||||
local lang = nil
|
||||
|
||||
local lang
|
||||
if fileinfo ~= nil then
|
||||
lang = require(TRANSLATION_PATH)
|
||||
lang.current = lang.default or "en"
|
||||
|
@ -133,9 +120,9 @@ function OptionsManager:getTranslationDefaultData()
|
|||
end
|
||||
|
||||
function OptionsManager:setLanguage(lang)
|
||||
if (self.core.lang:isLangAvailable(lang)) then
|
||||
if (self.controller.lang:isLangAvailable(lang)) then
|
||||
self.data.language.current = lang
|
||||
self.core.lang:getTranslationData()
|
||||
self.controller.lang:getTranslationData()
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -145,30 +132,11 @@ end
|
|||
-- FIXME: maybe subclass a special module for that ?
|
||||
|
||||
function OptionsManager:write()
|
||||
local data = self:getData()
|
||||
|
||||
local filepath = self:getFile(true)
|
||||
binser.writeFile(filepath, data)
|
||||
self:serialize(OPTION_FILE)
|
||||
end
|
||||
|
||||
function OptionsManager:read()
|
||||
local filepath = self:getFile(true)
|
||||
if utils.filesystem.exists("options.data") then
|
||||
local loadedDatas = binser.readFile(filepath)
|
||||
self.core.debug:logInfo("core/options", "data file found, loading it")
|
||||
self:setData(loadedDatas[1])
|
||||
else
|
||||
self:reset()
|
||||
self.core.debug:logInfo("core/options", "no data file found, reseting data")
|
||||
end
|
||||
end
|
||||
|
||||
function OptionsManager:getData(data)
|
||||
return self.data
|
||||
end
|
||||
|
||||
function OptionsManager:setData(data)
|
||||
self.data = data
|
||||
self:deserialize(OPTION_FILE)
|
||||
end
|
||||
|
||||
return OptionsManager
|
||||
|
|
|
@ -30,22 +30,19 @@ local SceneManager = Object:extend()
|
|||
|
||||
function SceneManager:new(controller)
|
||||
self.controller = controller
|
||||
self.timers = self.controller.modules.Timers(self)
|
||||
self.currentScene = nil
|
||||
self.nextScene = nil
|
||||
|
||||
self.storage = {}
|
||||
|
||||
self:initTransitions()
|
||||
end
|
||||
|
||||
function SceneManager:setScene(scene)
|
||||
if self.transition.isPrepared then
|
||||
self:startTransition(scene)
|
||||
else
|
||||
self.currentScene = scene
|
||||
self.currentScene:start()
|
||||
self.currentScene.isActive = true
|
||||
end
|
||||
--self.currentScene = nil
|
||||
self.nextScene = scene
|
||||
end
|
||||
|
||||
function SceneManager:haveStoredScene(name)
|
||||
return (self.storage[name] ~= nil)
|
||||
end
|
||||
|
||||
function SceneManager:storeCurrentScene(name)
|
||||
|
@ -57,6 +54,8 @@ function SceneManager:setStoredScene(name)
|
|||
if storedScene ~= nil then
|
||||
self.currentScene = storedScene
|
||||
self.storage[name] = nil
|
||||
collectgarbage()
|
||||
self.currentScene:restored()
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -72,7 +71,12 @@ end
|
|||
-- Update the current scene and its subobjects
|
||||
|
||||
function SceneManager:update(dt)
|
||||
self.timers:update(dt)
|
||||
if (self.nextScene ~= nil) then
|
||||
self.currentScene = self.nextScene
|
||||
self.nextScene = nil
|
||||
collectgarbage()
|
||||
end
|
||||
|
||||
if (self.currentScene ~= nil) then
|
||||
self.currentScene:updateScene(dt)
|
||||
end
|
||||
|
@ -86,14 +90,12 @@ function SceneManager:mousemoved(x, y, dx, dy)
|
|||
self.currentScene.mouse.x,
|
||||
self.currentScene.mouse.y = x, y
|
||||
self.currentScene:mousemoved(x, y, dx, dy)
|
||||
self.currentScene.menusystem:mousemoved(x, y, dx, dy)
|
||||
end
|
||||
end
|
||||
|
||||
function SceneManager:mousepressed( x, y, button, istouch )
|
||||
if (self.currentScene ~= nil) then
|
||||
self.currentScene:mousepressed( x, y, button, istouch )
|
||||
self.currentScene.menusystem:mousepressed( x, y, button, istouch )
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -101,55 +103,14 @@ end
|
|||
-- Add send keys functions to the scene
|
||||
|
||||
function SceneManager:keypressed( key, scancode, isrepeat )
|
||||
if (self.currentScene ~= nil) then
|
||||
self.currentScene:keypressed( key, scancode, isrepeat )
|
||||
end
|
||||
end
|
||||
|
||||
function SceneManager:keyreleased( key )
|
||||
if (self.currentScene ~= nil) then
|
||||
self.currentScene:keyreleased( key )
|
||||
end
|
||||
|
||||
-- TRANSITION FUNCTIONS
|
||||
-- Prepare transitionning to the next scene
|
||||
|
||||
function SceneManager:initTransitions()
|
||||
self.transition = {}
|
||||
|
||||
self.transition.easeIn = "inQuad"
|
||||
self.transition.easeOut = "outQuad"
|
||||
self.transition.duration = 1
|
||||
|
||||
self.transition.nextScene = nil
|
||||
self.transition.isPrepared = false
|
||||
end
|
||||
|
||||
function SceneManager:prepareTransition(duration, easeIn, easeOut)
|
||||
self.transition.easeIn = easeIn or self.transition.easeIn
|
||||
self.transition.easeOut = easeOut or self.transition.easeOut
|
||||
self.transition.duration = duration or self.transition.duration
|
||||
|
||||
self.transition.isPrepared = true
|
||||
end
|
||||
|
||||
function SceneManager:startTransition(nextScene)
|
||||
self.transition.nextScene = nextScene
|
||||
self.currentScene:flushKeys(self.transition.duration)
|
||||
self.currentScene.isActive = false
|
||||
self.transition.nextScene.isActive = false
|
||||
core.screen:fadeIn(self.transition.duration / 2.5, self.transition.easeIn)
|
||||
self.timers:newTimer(self.transition.duration / 2, "fadeOut")
|
||||
end
|
||||
|
||||
function SceneManager:timerResponse(timer)
|
||||
if timer == "fadeOut" then
|
||||
self.currentScene = self.transition.nextScene
|
||||
self.currentScene:start()
|
||||
self.currentScene:flushKeys(self.transition.duration / 2.5)
|
||||
self.currentScene.isActive = false
|
||||
core.screen:fadeOut(self.transition.duration / 2.5, self.transition.easeOut)
|
||||
self.transition.isPrepared = false
|
||||
self.timers:newTimer(self.transition.duration / 2.5, "activateScene")
|
||||
elseif timer == 'activateScene' then
|
||||
self.currentScene.isActive = true
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -164,4 +125,8 @@ function SceneManager:draw()
|
|||
self.controller.screen:cease()
|
||||
end
|
||||
|
||||
function SceneManager:redraw()
|
||||
self.currentScene:redraw()
|
||||
end
|
||||
|
||||
return SceneManager
|
||||
|
|
|
@ -39,9 +39,28 @@ function ScreenManager:new(controller)
|
|||
|
||||
love.graphics.setDefaultFilter( "nearest", "nearest", 1 )
|
||||
|
||||
self.timers = self.controller.modules.Timers(self)
|
||||
self.transition = nil
|
||||
self.transitionOut = nil
|
||||
self.isOpaque = false
|
||||
end
|
||||
|
||||
self.transitionValue = 0
|
||||
function ScreenManager:startTransition(transitionIn, transitionOut, func, x, y)
|
||||
self.transition = transitionIn(func, x, y, false)
|
||||
self.transitionOut = transitionOut(nil, x, y, true)
|
||||
self.isOpaque = true
|
||||
end
|
||||
|
||||
function ScreenManager:transitionOver(fadeOut)
|
||||
if (not fadeOut) then
|
||||
self.transition = self.transitionOut
|
||||
else
|
||||
self.transition = nil
|
||||
self.isOpaque = false
|
||||
end
|
||||
end
|
||||
|
||||
function ScreenManager:isActive()
|
||||
return ((self.transition == nil) and (not self.isOpaque))
|
||||
end
|
||||
|
||||
function ScreenManager:applySettings()
|
||||
|
@ -49,7 +68,7 @@ function ScreenManager:applySettings()
|
|||
|
||||
local flags = {}
|
||||
flags.vsync = self.data.vsync
|
||||
flags.borderless = (self.data.borderless)
|
||||
flags.borderless = (self.data.border == false)
|
||||
|
||||
love.window.setMode(self.width * self.data.resolution, self.height * self.data.resolution, flags)
|
||||
love.window.setFullscreen( self.data.fullscreen )
|
||||
|
@ -58,6 +77,12 @@ function ScreenManager:applySettings()
|
|||
CScreen.update(width, height)
|
||||
end
|
||||
|
||||
function ScreenManager:update(dt)
|
||||
if (self.transition ~= nil) then
|
||||
self.transition:update(dt)
|
||||
end
|
||||
end
|
||||
|
||||
-- POINTER FUNCTIONS
|
||||
-- Translate the pointer according to the screen coordinates
|
||||
|
||||
|
@ -96,35 +121,6 @@ function ScreenManager:resetScissor()
|
|||
love.graphics.setScissor( )
|
||||
end
|
||||
|
||||
-- UPDATE FUNCTIONS
|
||||
-- Update the screen
|
||||
|
||||
function ScreenManager:update(dt)
|
||||
self.timers:update(dt)
|
||||
end
|
||||
|
||||
-- TRANSITION FUNCTIONS
|
||||
-- Handle transitions
|
||||
|
||||
function ScreenManager:fadeIn(duration, easing)
|
||||
local duration = duration or 1
|
||||
local easing = easing or "inExpo"
|
||||
self.timers:newTween(0, duration, {transitionValue = 1}, easing)
|
||||
end
|
||||
|
||||
function ScreenManager:fadeOut(duration, easing)
|
||||
local duration = duration or 1
|
||||
local easing = easing or "outExpo"
|
||||
self.timers:newTween(0, duration, {transitionValue = 0}, easing)
|
||||
end
|
||||
|
||||
function ScreenManager:drawFade()
|
||||
local w, h = love.graphics.getDimensions()
|
||||
love.graphics.setColor(0, 0, 0, self.transitionValue)
|
||||
love.graphics.rectangle("fill", 0, 0, w, h)
|
||||
utils.graphics.resetColor()
|
||||
end
|
||||
|
||||
-- DRAW FUNCTIONS
|
||||
-- Apply draw functions to the scene
|
||||
|
||||
|
@ -136,4 +132,16 @@ function ScreenManager:cease()
|
|||
CScreen.cease()
|
||||
end
|
||||
|
||||
function ScreenManager:drawTransition()
|
||||
if (self.isOpaque) then
|
||||
if (self.transition ~= nil) then
|
||||
self.transition:draw()
|
||||
else
|
||||
love.graphics.setColor(0,0,0,1)
|
||||
love.graphics.rectangle("fill",0,0,424,240)
|
||||
utils.graphics.resetColor()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return ScreenManager
|
||||
|
|
102
birb/gamesystem/init.lua
Normal file
102
birb/gamesystem/init.lua
Normal file
|
@ -0,0 +1,102 @@
|
|||
-- GameSystem :: The main GameSystem subsystem. Basically a big object that handle all the
|
||||
-- GameSystem-related data like characters, monsters, etc. While the core aim to be
|
||||
-- reusable at will, the GameSystem is specifically made for the current GameSystem.
|
||||
|
||||
--[[
|
||||
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 Serializer = require "birb.classes.serializable.serializer"
|
||||
local GameSystem = Serializer:extend()
|
||||
|
||||
local VAR_TO_SERIALIZE = {
|
||||
"gametime",
|
||||
"destroyedGizmo",
|
||||
"variables",
|
||||
"flags"
|
||||
}
|
||||
|
||||
function GameSystem:new()
|
||||
self.slot = -1
|
||||
self.slotNumber = 3
|
||||
self.version = core.conf.gameversion or "N/A"
|
||||
self:reset()
|
||||
GameSystem.super.new(self, VAR_TO_SERIALIZE)
|
||||
end
|
||||
|
||||
function GameSystem:reset()
|
||||
self.gametime = 0
|
||||
|
||||
self.flags = {}
|
||||
self.destroyedGizmo = {}
|
||||
self.variables = {}
|
||||
self.mapName = ""
|
||||
end
|
||||
|
||||
function GameSystem:reload()
|
||||
self:read(self.slot)
|
||||
end
|
||||
|
||||
function GameSystem:read(save_id)
|
||||
self.slot = save_id
|
||||
if (self.slot > 0) then
|
||||
self:deserialize(self:getSaveName())
|
||||
end
|
||||
end
|
||||
|
||||
function GameSystem:deleteCurrentSave()
|
||||
if (self.slot > 0) then
|
||||
self:delete(self:getSaveName())
|
||||
self.metadata:remove(self.slot)
|
||||
end
|
||||
end
|
||||
|
||||
function GameSystem:write()
|
||||
if (self.slot > 0) then
|
||||
self:serialize(self:getSaveName())
|
||||
end
|
||||
end
|
||||
|
||||
function GameSystem:getSaveName(saveslot)
|
||||
local saveslot = saveslot or self.slot
|
||||
return "save" .. saveslot .. ".save"
|
||||
end
|
||||
|
||||
function GameSystem:resetSaves()
|
||||
for i=1, self.slotNumber do
|
||||
self:delete(self:getSaveName(i))
|
||||
end
|
||||
end
|
||||
|
||||
function GameSystem:update(dt)
|
||||
self.gametime = self.gametime + dt
|
||||
end
|
||||
|
||||
function GameSystem:getTime()
|
||||
return utils.time.getFields(self.gametime)
|
||||
end
|
||||
|
||||
function GameSystem:getTimeString()
|
||||
return utils.time.toString(self.gametime)
|
||||
end
|
||||
|
||||
function GameSystem:printTime()
|
||||
core.debug:print(self:getTimeString())
|
||||
end
|
||||
|
||||
return GameSystem
|
|
@ -1,8 +1,7 @@
|
|||
-- birb/init.lua :: The main file of birb, that initilize the whole birb engine
|
||||
-- It basically works by loading everything needed for a full birb experience.
|
||||
-- birb :: The main birb script, loading the core and main utilities
|
||||
|
||||
--[[
|
||||
Copyright © 2019 Kazhnuz
|
||||
Copyright © 2021 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
|
||||
|
@ -30,12 +29,24 @@ birb = {}
|
|||
|
||||
Object = require("birb.libs.classic")
|
||||
utils = require("birb.utils")
|
||||
enum = require("birb.utils.enum")
|
||||
|
||||
birb.modules = require("birb.modules")
|
||||
birb.Core = require("birb.core")
|
||||
|
||||
function birb.startCore(debugLevel)
|
||||
core = birb.Core(debugLevel)
|
||||
function birb.start(gamemodule, args)
|
||||
birb.startCore(args)
|
||||
if (gamemodule ~= nil) then
|
||||
birb.startGame(gamemodule)
|
||||
end
|
||||
end
|
||||
|
||||
function birb.startCore(args)
|
||||
core = birb.Core(args)
|
||||
end
|
||||
|
||||
function birb.startGame(gamemodule)
|
||||
local GameObject = require(gamemodule)
|
||||
game = GameObject()
|
||||
end
|
||||
|
||||
require("birb.callbacks")
|
392
birb/libs/talkies.lua
Normal file
392
birb/libs/talkies.lua
Normal file
|
@ -0,0 +1,392 @@
|
|||
--
|
||||
-- talkies
|
||||
--
|
||||
-- Copyright (c) 2017 twentytwoo, tanema
|
||||
--
|
||||
-- This library is free software; you can redistribute it and/or modify it
|
||||
-- under the terms of the MIT license. See LICENSE for details.
|
||||
--
|
||||
local utf8 = require("utf8")
|
||||
|
||||
local function playSound(sound, pitch)
|
||||
if type(sound) == "userdata" then
|
||||
sound:setPitch(pitch or 1)
|
||||
sound:play()
|
||||
end
|
||||
end
|
||||
|
||||
local function parseSpeed(speed)
|
||||
if speed == "fast" then return 0.01
|
||||
elseif speed == "medium" then return 0.04
|
||||
elseif speed == "slow" then return 0.08
|
||||
else
|
||||
assert(tonumber(speed), "setSpeed() - Expected number, got " .. tostring(speed))
|
||||
return speed
|
||||
end
|
||||
end
|
||||
|
||||
local Fifo = {}
|
||||
function Fifo.new () return setmetatable({first=1,last=0},{__index=Fifo}) end
|
||||
function Fifo:peek() return self[self.first] end
|
||||
function Fifo:len() return (self.last+1)-self.first end
|
||||
|
||||
function Fifo:push(value)
|
||||
self.last = self.last + 1
|
||||
self[self.last] = value
|
||||
end
|
||||
|
||||
function Fifo:pop()
|
||||
if self.first > self.last then return end
|
||||
local value = self[self.first]
|
||||
self[self.first] = nil
|
||||
self.first = self.first + 1
|
||||
return value
|
||||
end
|
||||
|
||||
local Typer = {}
|
||||
function Typer.new(msg, speed)
|
||||
local timeToType = parseSpeed(speed)
|
||||
return setmetatable({
|
||||
msg = msg, complete = false, paused = false,
|
||||
timer = timeToType, max = timeToType, position = 0, visible = "",
|
||||
},{__index=Typer})
|
||||
end
|
||||
|
||||
function Typer:resume()
|
||||
if not self.paused then return end
|
||||
self.msg = self.msg:gsub("%-%-", " ", 1)
|
||||
self.paused = false
|
||||
end
|
||||
|
||||
function Typer:finish()
|
||||
if self.complete then return end
|
||||
self.msg = self.msg:gsub("%-%-", " ")
|
||||
self.visible = self.msg
|
||||
self.complete = true
|
||||
end
|
||||
|
||||
function Typer:update(dt)
|
||||
local typed = false
|
||||
if self.complete then return typed end
|
||||
if not self.paused then
|
||||
self.timer = self.timer - dt
|
||||
while not self.paused and not self.complete and self.timer <= 0 do
|
||||
typed = string.sub(self.msg, self.position, self.position) ~= " "
|
||||
self.position = self.position + 1
|
||||
|
||||
self.timer = self.timer + self.max
|
||||
self.visible = string.sub(self.msg, 0, utf8.offset(self.msg, self.position) - 1)
|
||||
self.complete = (self.visible == self.msg)
|
||||
self.paused = string.sub(self.msg, string.len(self.visible)+1, string.len(self.visible)+2) == "--"
|
||||
end
|
||||
end
|
||||
|
||||
return typed
|
||||
end
|
||||
|
||||
local Talkies = {
|
||||
_VERSION = '0.0.1',
|
||||
_URL = 'https://github.com/tanema/talkies',
|
||||
_DESCRIPTION = 'A simple messagebox system for LÖVE',
|
||||
|
||||
-- Theme
|
||||
indicatorCharacter = ">>",
|
||||
optionCharacter = ">",
|
||||
padding = 4,
|
||||
talkSound = nil,
|
||||
optionSwitchSound = nil,
|
||||
optionOnSelectSound = nil,
|
||||
inlineOptions = true,
|
||||
|
||||
titleColor = {1, 1, 1},
|
||||
titleBackgroundColor = nil,
|
||||
titleBorderColor = nil,
|
||||
messageColor = {1, 1, 1},
|
||||
messageBackgroundColor = {0, 0, 0, 0.8},
|
||||
messageBorderColor = nil,
|
||||
|
||||
rounding = 0,
|
||||
thickness = 0,
|
||||
|
||||
textSpeed = 1 / 60,
|
||||
font = love.graphics.newFont(),
|
||||
|
||||
typedNotTalked = true,
|
||||
pitchValues = {0.7, 0.8, 1.0, 1.2, 1.3},
|
||||
|
||||
indicatorTimer = 0,
|
||||
indicatorDelay = 3,
|
||||
showIndicator = false,
|
||||
dialogs = Fifo.new(),
|
||||
}
|
||||
|
||||
function Talkies.say(title, messages, config)
|
||||
config = config or {}
|
||||
if type(messages) ~= "table" then
|
||||
messages = { messages }
|
||||
end
|
||||
|
||||
msgFifo = Fifo.new()
|
||||
|
||||
for i=1, #messages do
|
||||
msgFifo:push(Typer.new(messages[i], config.textSpeed or Talkies.textSpeed))
|
||||
end
|
||||
|
||||
local font = config.font or Talkies.font
|
||||
|
||||
-- Insert the Talkies.new into its own instance (table)
|
||||
local newDialog = {
|
||||
title = title or "",
|
||||
messages = msgFifo,
|
||||
image = config.image,
|
||||
options = config.options,
|
||||
onstart = config.onstart or function(dialog) end,
|
||||
onmessage = config.onmessage or function(dialog, left) end,
|
||||
oncomplete = config.oncomplete or function(dialog) end,
|
||||
|
||||
-- theme
|
||||
indicatorCharacter = config.indicatorCharacter or Talkies.indicatorCharacter,
|
||||
optionCharacter = config.optionCharacter or Talkies.optionCharacter,
|
||||
padding = config.padding or Talkies.padding,
|
||||
rounding = config.rounding or Talkies.rounding,
|
||||
thickness = config.thickness or Talkies.thickness,
|
||||
talkSound = config.talkSound or Talkies.talkSound,
|
||||
optionSwitchSound = config.optionSwitchSound or Talkies.optionSwitchSound,
|
||||
optionOnSelectSound = config.optionOnSelectSound or Talkies.optionOnSelectSound,
|
||||
inlineOptions = config.inlineOptions or Talkies.inlineOptions,
|
||||
font = font,
|
||||
fontHeight = font:getHeight(" "),
|
||||
typedNotTalked = config.typedNotTalked == nil and Talkies.typedNotTalked or config.typedNotTalked,
|
||||
pitchValues = config.pitchValues or Talkies.pitchValues,
|
||||
|
||||
optionIndex = 1,
|
||||
|
||||
showOptions = function(dialog) return dialog.messages:len() == 1 and type(dialog.options) == "table" end,
|
||||
isShown = function(dialog) return Talkies.dialogs:peek() == dialog end
|
||||
}
|
||||
|
||||
newDialog.messageBackgroundColor = config.messageBackgroundColor or Talkies.messageBackgroundColor
|
||||
newDialog.titleBackgroundColor = config.titleBackgroundColor or Talkies.titleBackgroundColor or newDialog.messageBackgroundColor
|
||||
|
||||
newDialog.messageColor = config.messageColor or Talkies.messageColor
|
||||
newDialog.titleColor = config.titleColor or Talkies.titleColor or newDialog.messageColor
|
||||
|
||||
newDialog.messageBorderColor = config.messageBorderColor or Talkies.messageBorderColor or newDialog.messageBackgroundColor
|
||||
newDialog.titleBorderColor = config.titleBorderColor or Talkies.titleBorderColor or newDialog.messageBorderColor
|
||||
|
||||
Talkies.dialogs:push(newDialog)
|
||||
if Talkies.dialogs:len() == 1 then
|
||||
Talkies.dialogs:peek():onstart()
|
||||
end
|
||||
|
||||
return newDialog
|
||||
end
|
||||
|
||||
function Talkies.update(dt)
|
||||
local currentDialog = Talkies.dialogs:peek()
|
||||
if currentDialog == nil then return end
|
||||
local currentMessage = currentDialog.messages:peek()
|
||||
|
||||
if currentMessage.paused or currentMessage.complete then
|
||||
Talkies.indicatorTimer = Talkies.indicatorTimer + (10 * dt)
|
||||
if Talkies.indicatorTimer > Talkies.indicatorDelay then
|
||||
Talkies.showIndicator = not Talkies.showIndicator
|
||||
Talkies.indicatorTimer = 0
|
||||
end
|
||||
else
|
||||
Talkies.showIndicator = false
|
||||
end
|
||||
|
||||
if currentMessage:update(dt) then
|
||||
if currentDialog.typedNotTalked then
|
||||
playSound(currentDialog.talkSound)
|
||||
elseif not currentDialog.talkSound:isPlaying() then
|
||||
local pitch = currentDialog.pitchValues[math.random(#currentDialog.pitchValues)]
|
||||
playSound(currentDialog.talkSound, pitch)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function Talkies.advanceMsg()
|
||||
local currentDialog = Talkies.dialogs:peek()
|
||||
if currentDialog == nil then return end
|
||||
currentDialog:onmessage(currentDialog.messages:len() - 1)
|
||||
if currentDialog.messages:len() == 1 then
|
||||
Talkies.dialogs:pop()
|
||||
currentDialog:oncomplete()
|
||||
if Talkies.dialogs:len() == 0 then
|
||||
Talkies.clearMessages()
|
||||
else
|
||||
Talkies.dialogs:peek():onstart()
|
||||
end
|
||||
end
|
||||
currentDialog.messages:pop()
|
||||
end
|
||||
|
||||
function Talkies.isOpen()
|
||||
return Talkies.dialogs:peek() ~= nil
|
||||
end
|
||||
|
||||
function Talkies.draw()
|
||||
local currentDialog = Talkies.dialogs:peek()
|
||||
if currentDialog == nil then return end
|
||||
|
||||
local currentMessage = currentDialog.messages:peek()
|
||||
|
||||
--love.graphics.push()
|
||||
love.graphics.setDefaultFilter("nearest", "nearest")
|
||||
|
||||
local function getDimensions()
|
||||
return core.screen:getDimensions()
|
||||
end
|
||||
|
||||
local windowWidth, windowHeight = getDimensions()
|
||||
|
||||
love.graphics.setLineWidth(currentDialog.thickness)
|
||||
|
||||
-- message box
|
||||
local boxW = windowWidth---(2*currentDialog.padding)
|
||||
local boxH = (windowHeight/3)--(2*currentDialog.padding)
|
||||
local boxX = 0--currentDialog.padding
|
||||
local boxY = windowHeight-(boxH+currentDialog.padding)
|
||||
|
||||
-- image
|
||||
local imgX, imgY, imgW, imgScale = boxX+currentDialog.padding, boxY+currentDialog.padding, 0, 0
|
||||
if currentDialog.image ~= nil then
|
||||
imgScale = (boxH - (currentDialog.padding * 2)) / currentDialog.image:getHeight()
|
||||
imgW = currentDialog.image:getWidth() * imgScale
|
||||
end
|
||||
|
||||
-- title box
|
||||
local textX, textY = imgX + imgW + currentDialog.padding, boxY + 4
|
||||
|
||||
love.graphics.setFont(currentDialog.font)
|
||||
|
||||
if currentDialog.title ~= "" then
|
||||
local titleBoxW = currentDialog.font:getWidth(currentDialog.title)+(4*currentDialog.padding)
|
||||
local titleBoxH = currentDialog.fontHeight+currentDialog.padding
|
||||
local titleBoxY = boxY-titleBoxH-(currentDialog.padding/2)
|
||||
local titleBoxX = currentDialog.padding * 2
|
||||
local titleX, titleY = titleBoxX + currentDialog.padding*2, titleBoxY + 2
|
||||
|
||||
-- Message title
|
||||
love.graphics.setColor(currentDialog.titleBackgroundColor)
|
||||
love.graphics.rectangle("fill", titleBoxX, titleBoxY, titleBoxW, titleBoxH, titleBoxH/2, titleBoxH/2)
|
||||
if currentDialog.thickness > 0 then
|
||||
love.graphics.setColor(currentDialog.titleBorderColor)
|
||||
love.graphics.rectangle("line", boxX, titleBoxY, titleBoxW, titleBoxH, currentDialog.rounding, currentDialog.rounding)
|
||||
end
|
||||
love.graphics.setColor(currentDialog.titleColor)
|
||||
love.graphics.print(currentDialog.title, titleX, titleY)
|
||||
end
|
||||
|
||||
-- Main message box
|
||||
love.graphics.setColor(currentDialog.messageBackgroundColor)
|
||||
love.graphics.rectangle("fill", boxX, boxY, boxW, boxH, currentDialog.rounding, currentDialog.rounding)
|
||||
if currentDialog.thickness > 0 then
|
||||
love.graphics.setColor(currentDialog.messageBorderColor)
|
||||
love.graphics.rectangle("line", boxX, boxY, boxW, boxH, currentDialog.rounding, currentDialog.rounding)
|
||||
end
|
||||
|
||||
-- Message avatar
|
||||
if currentDialog.image ~= nil then
|
||||
love.graphics.push()
|
||||
love.graphics.setColor(1, 1, 1)
|
||||
love.graphics.draw(currentDialog.image, imgX, imgY, 0, imgScale, imgScale)
|
||||
love.graphics.pop()
|
||||
end
|
||||
|
||||
-- Message text
|
||||
love.graphics.setColor(currentDialog.messageColor)
|
||||
local textW = boxW - imgW - (4 * currentDialog.padding)
|
||||
local _, modmsg = currentDialog.font:getWrap(currentMessage.msg, textW)
|
||||
local catmsg = table.concat(modmsg, "\n")
|
||||
|
||||
local display = string.sub(catmsg, 1, #currentMessage.visible + #modmsg - 1)
|
||||
|
||||
love.graphics.print(display, textX, textY)
|
||||
|
||||
-- Message options (when shown)
|
||||
if currentDialog:showOptions() and currentMessage.complete then
|
||||
if currentDialog.inlineOptions then
|
||||
local optionsY = textY+currentDialog.font:getHeight(currentMessage.visible)-(currentDialog.padding/1.6)
|
||||
local optionLeftPad = currentDialog.font:getWidth(currentDialog.optionCharacter.." ")
|
||||
for k, option in pairs(currentDialog.options) do
|
||||
love.graphics.print(option[1], optionLeftPad+textX+currentDialog.padding, optionsY+((k-1)*currentDialog.fontHeight))
|
||||
end
|
||||
love.graphics.print(
|
||||
currentDialog.optionCharacter.." ",
|
||||
textX+currentDialog.padding,
|
||||
optionsY+((currentDialog.optionIndex-1)*currentDialog.fontHeight))
|
||||
else
|
||||
local optionWidth = 0
|
||||
|
||||
local optionText = ""
|
||||
for k, option in pairs(currentDialog.options) do
|
||||
local newText = (currentDialog.optionIndex == k and currentDialog.optionCharacter or " ") .. " " .. option[1]
|
||||
optionWidth = math.max(optionWidth, currentDialog.font:getWidth(newText) )
|
||||
optionText = optionText .. newText .. "\n"
|
||||
end
|
||||
|
||||
local optionsH = (currentDialog.font:getHeight() * #currentDialog.options)
|
||||
local optionsX = math.floor((windowWidth / 2) - (optionWidth / 2))
|
||||
local optionsY = math.floor((windowHeight / 3) - (optionsH / 2))
|
||||
|
||||
love.graphics.setColor(currentDialog.messageBackgroundColor)
|
||||
love.graphics.rectangle("fill", optionsX - currentDialog.padding, optionsY - currentDialog.padding, optionWidth + currentDialog.padding * 2, optionsH + currentDialog.padding * 2, currentDialog.rounding, currentDialog.rounding)
|
||||
|
||||
if currentDialog.thickness > 0 then
|
||||
love.graphics.setColor(currentDialog.messageBorderColor)
|
||||
love.graphics.rectangle("line", optionsX - currentDialog.padding, optionsY - currentDialog.padding, optionWidth + currentDialog.padding * 2, optionsH + currentDialog.padding * 2, currentDialog.rounding, currentDialog.rounding)
|
||||
end
|
||||
|
||||
love.graphics.setColor(currentDialog.messageColor)
|
||||
love.graphics.print(optionText, optionsX, optionsY)
|
||||
end
|
||||
end
|
||||
|
||||
-- Next message/continue indicator
|
||||
if Talkies.showIndicator then
|
||||
love.graphics.print(currentDialog.indicatorCharacter, boxX+boxW-(4*currentDialog.padding), boxY+boxH-currentDialog.fontHeight)
|
||||
end
|
||||
|
||||
--love.graphics.pop()
|
||||
end
|
||||
|
||||
function Talkies.prevOption()
|
||||
local currentDialog = Talkies.dialogs:peek()
|
||||
if currentDialog == nil or not currentDialog:showOptions() then return end
|
||||
currentDialog.optionIndex = currentDialog.optionIndex - 1
|
||||
if currentDialog.optionIndex < 1 then currentDialog.optionIndex = #currentDialog.options end
|
||||
playSound(currentDialog.optionSwitchSound)
|
||||
end
|
||||
|
||||
function Talkies.nextOption()
|
||||
local currentDialog = Talkies.dialogs:peek()
|
||||
if currentDialog == nil or not currentDialog:showOptions() then return end
|
||||
currentDialog.optionIndex = currentDialog.optionIndex + 1
|
||||
if currentDialog.optionIndex > #currentDialog.options then currentDialog.optionIndex = 1 end
|
||||
playSound(currentDialog.optionSwitchSound)
|
||||
end
|
||||
|
||||
function Talkies.onAction()
|
||||
local currentDialog = Talkies.dialogs:peek()
|
||||
if currentDialog == nil then return end
|
||||
local currentMessage = currentDialog.messages:peek()
|
||||
|
||||
if currentMessage.paused then currentMessage:resume()
|
||||
elseif not currentMessage.complete then currentMessage:finish()
|
||||
else
|
||||
if currentDialog:showOptions() then
|
||||
currentDialog.options[currentDialog.optionIndex][2]() -- Execute the selected function
|
||||
playSound(currentDialog.optionOnSelectSound)
|
||||
end
|
||||
Talkies.advanceMsg()
|
||||
end
|
||||
end
|
||||
|
||||
function Talkies.clearMessages()
|
||||
Talkies.dialogs = Fifo.new()
|
||||
end
|
||||
|
||||
return Talkies
|
|
@ -1,5 +1,5 @@
|
|||
-- modules/assets/import :: a simple assets importer, to import easily everything into
|
||||
-- the asset manager.
|
||||
-- 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
|
||||
|
@ -41,89 +41,31 @@ local SFX = require(cwd .. "sfx")
|
|||
-- INIT FUNCTIONS
|
||||
-- Initilizing and configuring option
|
||||
|
||||
function Assets:new(isGlobal)
|
||||
self.isGlobal = isGlobal
|
||||
function Assets:new()
|
||||
self:clear()
|
||||
|
||||
self.isActive = true
|
||||
end
|
||||
|
||||
function Assets:clear()
|
||||
if (self.isGlobal) then
|
||||
core.assets:clear()
|
||||
else
|
||||
core.assets:clearLocal()
|
||||
-- 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
|
||||
|
||||
-- WRAPPER FUNCTIONS
|
||||
-- Basic wrappers to ensure compatibility
|
||||
|
||||
function Assets:get(key)
|
||||
return core.assets:get(key)
|
||||
end
|
||||
|
||||
function Assets:getFont(key)
|
||||
return self:getWithType(key, "font")
|
||||
end
|
||||
|
||||
function Assets:getWithType(key, type)
|
||||
return core.assets:get(key)
|
||||
end
|
||||
|
||||
function Assets:draw(name, x, y, r, sx, sy, ox, oy, kx, ky)
|
||||
core.assets:draw(name, x, y, r, sx, sy, ox, oy, kx, ky)
|
||||
end
|
||||
|
||||
function Assets:newSFX(name, filepath)
|
||||
self:addSFX(name, filepath)
|
||||
end
|
||||
|
||||
function Assets:addImage(name, filename)
|
||||
self:addTexture(name, filename)
|
||||
end
|
||||
|
||||
function Assets:playSFX(name)
|
||||
core.assets:playSFX(name)
|
||||
end
|
||||
|
||||
function Assets:drawImage(name, x, y, r, sx, sy, ox, oy, kx, ky)
|
||||
self:draw(name, x, y, r, sx, sy, ox, oy, kx, ky)
|
||||
end
|
||||
|
||||
-- Music
|
||||
|
||||
function Assets:setMusic(filename, loop)
|
||||
core.debug:logDebug("assets", "Assets:setMusic is deprecated")
|
||||
core.music:addMusic(filename, true)
|
||||
end
|
||||
|
||||
function Assets:silence()
|
||||
core.debug:logDebug("assets", "Assets:silence is deprecated")
|
||||
core.music:silence()
|
||||
end
|
||||
|
||||
function Assets:resetMusic()
|
||||
core.debug:logDebug("assets", "Assets:resetMusic is deprecated")
|
||||
core.music:purge()
|
||||
end
|
||||
|
||||
function Assets:playMusic()
|
||||
core.debug:logDebug("assets", "Assets:playMusic is deprecated")
|
||||
core.music:playMusic()
|
||||
end
|
||||
|
||||
-- Activity
|
||||
|
||||
function Assets:setActivity(activity)
|
||||
core.assets:setActivity(activity)
|
||||
end
|
||||
|
||||
function Assets:switchActivity()
|
||||
core.assets:switchActivity()
|
||||
end
|
||||
|
||||
function Assets:getActivity()
|
||||
core.assets:getActivity()
|
||||
end
|
||||
|
||||
-- IMPORT FUNCTIONS
|
||||
-- Easilly import assets
|
||||
|
||||
|
@ -150,7 +92,7 @@ function Assets:batchImport(datafile)
|
|||
elseif (asset_type == "sfx") then
|
||||
self:importSFX(assets)
|
||||
else
|
||||
core.debug:logWarn("assets/importer", "unkown asset type " .. asset_type)
|
||||
core.debug:warning("assets/importer", "unkown asset type " .. asset_type)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -203,74 +145,153 @@ function Assets:importSFX(assets)
|
|||
end
|
||||
end
|
||||
|
||||
-- ADD FUNCTIONS
|
||||
-- Different wrapper to create easily asset objects
|
||||
|
||||
function Assets:add(name, assetObject)
|
||||
core.assets:add(name, assetObject, self.isGlobal)
|
||||
end
|
||||
|
||||
function Assets:addBackground(name, filepath)
|
||||
self:add(name, Background(filepath))
|
||||
end
|
||||
|
||||
function Assets:addSprite(name, filepath)
|
||||
self:add(name, Sprite(filepath))
|
||||
end
|
||||
|
||||
function Assets:addFont(key, filename, size)
|
||||
self:add(key, Font(filename, size))
|
||||
end
|
||||
|
||||
function Assets:addImageFont(key, filename, extraspacing)
|
||||
self:add(key, ImageFont(filename, extraspacing))
|
||||
end
|
||||
|
||||
function Assets:addTileset(name, filepath)
|
||||
self:add(name, Tileset(filepath))
|
||||
end
|
||||
|
||||
function Assets:addAutotile(name, tilesize)
|
||||
self:add(name, Autotile(name, tilesize))
|
||||
end
|
||||
-- SFX & MUSICS
|
||||
-- Handle sound effects and musics
|
||||
|
||||
function Assets:addSFX(name, filepath)
|
||||
self:add(name, SFX(filepath))
|
||||
self:newSFX(name, filepath)
|
||||
end
|
||||
|
||||
function Assets:addTexture(name, filename)
|
||||
self:add(name, Texture(filename))
|
||||
end
|
||||
|
||||
-- DEPRECATED FUNCTIONS
|
||||
-- Don't do anything and will be removed soon
|
||||
|
||||
function Assets:clearFonts()
|
||||
core.debug:logDebug("assets", "Assets:clearFonts is deprecated")
|
||||
end
|
||||
|
||||
function Assets:clearTileset()
|
||||
core.debug:logDebug("assets", "Assets:clearTileset is deprecated")
|
||||
end
|
||||
|
||||
function Assets:clearAutotile()
|
||||
core.debug:logDebug("assets", "Assets:clearAutotile is deprecated")
|
||||
function Assets:newSFX(name, filepath)
|
||||
self.sfx[name] = SFX( filepath )
|
||||
end
|
||||
|
||||
function Assets:clearSFX()
|
||||
core.debug:logDebug("assets", "Assets:clearSFX is deprecated")
|
||||
love.audio.stop( )
|
||||
self.sfx = {}
|
||||
end
|
||||
|
||||
function Assets:clearBackgrounds()
|
||||
core.debug:logDebug("assets", "Assets:clearBackgrounds is deprecated")
|
||||
function Assets:playSFX(filename)
|
||||
if not (self.sfx[filename] == nil) then
|
||||
self.sfx[filename]:play()
|
||||
end
|
||||
end
|
||||
|
||||
function Assets:clearSprites()
|
||||
core.debug:logDebug("assets", "Assets:clearSprites is deprecated")
|
||||
-- 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()
|
||||
core.debug:logDebug("assets", "Assets:clearImages is deprecated")
|
||||
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
|
||||
|
|
|
@ -35,6 +35,7 @@ function Animator:new(sprite)
|
|||
self.animationData = {}
|
||||
|
||||
self.customSpeed = 0
|
||||
self.speedFactor = 1
|
||||
|
||||
self:changeToDefaultAnimation()
|
||||
end
|
||||
|
@ -43,12 +44,16 @@ function Animator:setCustomSpeed(customSpeed)
|
|||
self.customSpeed = customSpeed or 0
|
||||
end
|
||||
|
||||
function Animator:setSpeedFactor(speedFactor)
|
||||
self.speedFactor = speedFactor or 1
|
||||
end
|
||||
|
||||
-- UPDATE FUNCTIONS
|
||||
-- Update the animation of the animator
|
||||
|
||||
function Animator:update(dt)
|
||||
if (self.currentAnimation == "") then
|
||||
core.debug:logWarn("animator", "no current animation data")
|
||||
core.debug:warning("animator", "no current animation data")
|
||||
return 0
|
||||
end
|
||||
|
||||
|
@ -56,16 +61,17 @@ function Animator:update(dt)
|
|||
if (self.animationData.speed) == -1 then
|
||||
speed = self.customSpeed --math.abs(self.xsp / 16)
|
||||
end
|
||||
self.frameTimer = self.frameTimer + (speed * dt)
|
||||
self.frameTimer = self.frameTimer + (speed * dt * self.speedFactor)
|
||||
if self.frameTimer > 1 then
|
||||
self.frameTimer = 0
|
||||
if self.frame == self.animationData.endAt then
|
||||
self:sendCallback()
|
||||
if not (self.animationData.pauseAtEnd) then
|
||||
self.frame = self.animationData.loop
|
||||
end
|
||||
self:sendCallback()
|
||||
else
|
||||
self.frame = self.frame + 1
|
||||
self:sendFrameSignal()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -124,17 +130,39 @@ end
|
|||
-- CALLBACK FUNCTIONS
|
||||
-- Handle getting a calback from the animation system
|
||||
|
||||
function Animator:setCallbackTarget(callbackTarget)
|
||||
self.callbackTarget = callbackTarget
|
||||
function Animator:setCallbackTarget(actor)
|
||||
self.actor = actor
|
||||
end
|
||||
|
||||
function Animator:setCallback(actor)
|
||||
core.debug:warning("Animator", "Animator:setCallback is deprecated, prefer Animator:setCallbackTarget instead")
|
||||
self:setCallbackTarget(actor)
|
||||
end
|
||||
|
||||
function Animator:sendCallback()
|
||||
if (self.callbackTarget ~= nil) then
|
||||
if (self.callbackTarget.animationEnded ~= nil) then
|
||||
self.callbackTarget:animationEnded(self.currentAnimation)
|
||||
if (self.actor ~= nil) then
|
||||
self.actor: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
|
||||
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])
|
||||
end
|
||||
end
|
||||
|
||||
-- DRAW FUNCTIONS
|
||||
-- Draw animations using these functions
|
||||
|
||||
|
|
|
@ -64,7 +64,6 @@ function Font:setAlign(align)
|
|||
end
|
||||
|
||||
function Font:setFilter(filter)
|
||||
local filter = filter or ""
|
||||
self.filter = filter
|
||||
end
|
||||
|
||||
|
@ -94,14 +93,6 @@ function Font:getColor()
|
|||
return self.color
|
||||
end
|
||||
|
||||
function Font:getFilter()
|
||||
return self.filter
|
||||
end
|
||||
|
||||
function Font:haveFilter()
|
||||
return ((self.filter ~= "") and (self.filter ~= nil))
|
||||
end
|
||||
|
||||
-- DRAW FUNCTIONS
|
||||
-- print text using theses functions
|
||||
|
||||
|
@ -149,8 +140,8 @@ function Font:applyFilter(text, x, y, limit, align, r, sx, sy, ox, oy, kx, ky)
|
|||
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)
|
||||
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
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
-- assets/sfx :: the sfx object, essentially used to be able to just have an sfx
|
||||
-- assets/sfx :: the sfx object
|
||||
|
||||
--[[
|
||||
Copyright © 2020 Kazhnuz
|
||||
Copyright © 2021 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,21 +20,31 @@
|
|||
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
|
||||
|
||||
function SFX:new(filepath)
|
||||
self.sound = love.audio.newSource(filepath, "static")
|
||||
self.source = love.audio.newSource(filepath, "static")
|
||||
end
|
||||
|
||||
-- INFO FUNCTIONS
|
||||
-- get information with these functions
|
||||
|
||||
-- None for the moment
|
||||
|
||||
-- DRAW FUNCTIONS
|
||||
-- Draw texture using these functions
|
||||
|
||||
function SFX:play()
|
||||
self.sound:stop()
|
||||
self.sound:setVolume(core.options.data.audio.sfx / 100)
|
||||
love.audio.play(self.sound)
|
||||
self.source:stop()
|
||||
self.source:setVolume(core.options.data.audio.sfx / 100)
|
||||
love.audio.play(self.source)
|
||||
end
|
||||
|
||||
function SFX:stop()
|
||||
self.source:stop()
|
||||
end
|
||||
|
||||
return SFX
|
||||
|
|
|
@ -63,6 +63,10 @@ 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
|
||||
|
||||
|
@ -93,11 +97,11 @@ end
|
|||
-- DRAW FUNCTIONS
|
||||
-- Draw sprites using these functions
|
||||
|
||||
function Sprite:drawAnimation(x, y, r, sx, sy, ox, oy, kx, ky)
|
||||
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:drawAnimationMask(x, y, r, sx, sy, ox, oy, kx, ky)
|
||||
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
|
||||
|
||||
|
@ -118,7 +122,7 @@ function Sprite:drawPart(x, y, w, h, r, sx, sy, ox, oy, kx, ky)
|
|||
end
|
||||
|
||||
love.graphics.setScissor(x - ox, y - oy, w, h)
|
||||
self:drawAnimation(x, y, r, sx, sy, ox, oy, kx, ky)
|
||||
self:draw(x, y, r, sx, sy, ox, oy, kx, ky)
|
||||
love.graphics.setScissor( )
|
||||
end
|
||||
|
||||
|
|
|
@ -1,144 +0,0 @@
|
|||
-- game :: The main game subsystem. Basically a big object that handle all the
|
||||
-- game-related data like characters, monsters, etc. While the core aim to be
|
||||
-- reusable at will, the game is specifically made for the current game.
|
||||
|
||||
-- It's also what handle the savedata for games
|
||||
|
||||
--[[
|
||||
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('%.init$', '') .. "."
|
||||
|
||||
local GameSystem = Object:extend()
|
||||
local binser = require("birb.libs.binser")
|
||||
|
||||
local DEFAULT_SAVENUMBER = 3
|
||||
|
||||
function GameSystem:new()
|
||||
self.currentSlot = -1
|
||||
|
||||
self.submodules = {}
|
||||
self.playtime = 0
|
||||
self:register()
|
||||
end
|
||||
|
||||
function GameSystem:register()
|
||||
core:registerGameSystem(self)
|
||||
end
|
||||
|
||||
function GameSystem:registerSubmodules(submodule)
|
||||
local name = submodule.name
|
||||
self.submodules[name] = submodule
|
||||
end
|
||||
|
||||
-- UPDATE FUNCTIONS
|
||||
-- Update every submodules
|
||||
|
||||
function GameSystem:update(dt)
|
||||
self.playtime = self.playtime + dt
|
||||
for k, submodule in pairs(self.submodules) do
|
||||
submodule:update(dt)
|
||||
end
|
||||
end
|
||||
|
||||
-- DATA MANAGEMENT FUNCTIONS
|
||||
-- Get and set data in the gamesystem object
|
||||
|
||||
function GameSystem:setData(data)
|
||||
local data = data
|
||||
self.playtime = data.playtime
|
||||
for k, submodule in pairs(self.submodules) do
|
||||
submodule:setData(data[k])
|
||||
end
|
||||
end
|
||||
|
||||
function GameSystem:getData()
|
||||
local data = {}
|
||||
data.playtime = self.playtime
|
||||
for k, submodule in pairs(self.submodules) do
|
||||
data[k] = submodule:getData()
|
||||
end
|
||||
return data
|
||||
end
|
||||
|
||||
-- SAVE MANAGEMENT FUNCTIONS
|
||||
-- Get and set data in the gamesystem object
|
||||
|
||||
function GameSystem:getSaveNumber()
|
||||
return DEFAULT_SAVENUMBER
|
||||
end
|
||||
|
||||
function GameSystem:resetSave(saveid)
|
||||
if utils.filesystem.exists("save" .. saveid .. ".save") then
|
||||
love.filesystem.remove( "save" .. saveid .. ".save" )
|
||||
end
|
||||
end
|
||||
|
||||
function GameSystem:resetAllSaves()
|
||||
for i=1, self:getSaveNumber() do
|
||||
self:resetSave(i)
|
||||
end
|
||||
end
|
||||
|
||||
function GameSystem:getSavePath(saveid, absolute)
|
||||
local saveDir = ""
|
||||
if (absolute) then
|
||||
saveDir = love.filesystem.getSaveDirectory() .. "/"
|
||||
if not utils.filesystem.exists(saveDir) then
|
||||
love.filesystem.createDirectory( "" )
|
||||
end
|
||||
end
|
||||
|
||||
local filepath = saveDir .. self:getSaveName(saveid)
|
||||
|
||||
return filepath
|
||||
end
|
||||
|
||||
function GameSystem:getSaveName(saveid)
|
||||
return "save" .. saveid .. ".save"
|
||||
end
|
||||
|
||||
function GameSystem:saveFileExist(saveid)
|
||||
return utils.filesystem.exists(self:getSaveName(saveid))
|
||||
end
|
||||
|
||||
function GameSystem:read(saveid)
|
||||
self.currentSlot = saveid or self.currentSlot
|
||||
if (self.currentSlot > 0) then
|
||||
local savepath = self:getSavePath(self.currentSlot, true)
|
||||
if self:saveFileExist(self.currentSlot) then
|
||||
local datas = binser.readFile(savepath)
|
||||
|
||||
self:setData(datas[1])
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function GameSystem:write()
|
||||
if (self.currentSlot > 0) then
|
||||
local data = self:getData()
|
||||
|
||||
local savepath = self:getSavePath(self.currentSlot, true)
|
||||
binser.writeFile(savepath, data)
|
||||
end
|
||||
end
|
||||
|
||||
return GameSystem
|
|
@ -1,23 +0,0 @@
|
|||
local SubModule = Object:extend()
|
||||
|
||||
function SubModule:new(game, name)
|
||||
self.name = name or error("SUBMODULE must have a name")
|
||||
self.game = game
|
||||
self.data = {}
|
||||
|
||||
self:register()
|
||||
end
|
||||
|
||||
function SubModule:register()
|
||||
self.game:registerSubmodules(self)
|
||||
end
|
||||
|
||||
function SubModule:getData()
|
||||
return self.data
|
||||
end
|
||||
|
||||
function SubModule:setData(data)
|
||||
self.data = data
|
||||
end
|
||||
|
||||
return SubModule
|
16
birb/modules/gui/elements/assets.lua
Normal file
16
birb/modules/gui/elements/assets.lua
Normal file
|
@ -0,0 +1,16 @@
|
|||
local Parent = require "birb.modules.gui.elements.drawable"
|
||||
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]
|
||||
assert(asset ~= nil, assetName .. ' (' .. assetType .. ") doesn't exist")
|
||||
|
||||
AssetElement.super.new(self, name, asset, x, y,r,sx,sy,ox,oy, opacity)
|
||||
end
|
||||
|
||||
function AssetElement:draw()
|
||||
self.drawable:draw(self.x,self.y,self.r,self.sx,self.sy,self.ox,self.oy)
|
||||
end
|
||||
|
||||
return AssetElement
|
96
birb/modules/gui/elements/canvas.lua
Normal file
96
birb/modules/gui/elements/canvas.lua
Normal file
|
@ -0,0 +1,96 @@
|
|||
local Parent = require "birb.modules.gui.elements.parent"
|
||||
local CanvasElement = Parent:extend()
|
||||
|
||||
function CanvasElement:new(name, x, y, w, h, r,sx,sy,ox,oy, opacity)
|
||||
self:initCanvas()
|
||||
CanvasElement.super.new(self, name, x, y, w, h)
|
||||
self.r = r or 0
|
||||
self.sx, self.sy = sx or 1, sy or 1
|
||||
self.ox, self.oy = self:parseOrigin(ox, w), self:parseOrigin(oy, h)
|
||||
self.opacity = opacity or 1
|
||||
end
|
||||
|
||||
function CanvasElement:initCanvas()
|
||||
self.canvas = {}
|
||||
self.canvas.needRedraw = true
|
||||
self.canvas.texture = nil
|
||||
self.canvas.isAnimated = false
|
||||
self.canvas.padding = 8
|
||||
self.canvas.final = nil
|
||||
self.canvas.dual = false
|
||||
end
|
||||
|
||||
function CanvasElement:updateElement(dt)
|
||||
CanvasElement.super.updateElement(self, dt)
|
||||
end
|
||||
|
||||
function CanvasElement:getCanvasDimensions()
|
||||
return self:getDimensions()
|
||||
end
|
||||
|
||||
function CanvasElement:redraw()
|
||||
if (self.canvas.needRedraw or self.canvas.isAnimated) then
|
||||
self:generateTexture()
|
||||
end
|
||||
|
||||
if (self.canvas.dual) then
|
||||
local w, h = self:getDimensions()
|
||||
local canvas = love.graphics.newCanvas(w + (self.canvas.padding*2), h + (self.canvas.padding*2))
|
||||
love.graphics.setCanvas(canvas)
|
||||
|
||||
love.graphics.draw(self.canvas.texture, 0, 0)
|
||||
self:drawFinalTexture()
|
||||
|
||||
self.canvas.final = canvas
|
||||
love.graphics.setCanvas()
|
||||
end
|
||||
end
|
||||
|
||||
function CanvasElement:generateTexture()
|
||||
local w, h = self:getDimensions()
|
||||
|
||||
local canvas = love.graphics.newCanvas(w + (self.canvas.padding*2), h + (self.canvas.padding*2))
|
||||
love.graphics.setCanvas(canvas)
|
||||
|
||||
self:drawTexture()
|
||||
self.canvas.needRedraw = false
|
||||
love.graphics.setCanvas()
|
||||
if (self.canvas.isAnimated) then
|
||||
self.canvas.texture = canvas
|
||||
else
|
||||
local imageData = canvas:newImageData()
|
||||
self.canvas.texture = love.graphics.newImage(imageData)
|
||||
canvas:release()
|
||||
imageData:release()
|
||||
end
|
||||
end
|
||||
|
||||
function CanvasElement:drawTexture()
|
||||
|
||||
end
|
||||
|
||||
function CanvasElement:drawFinalTexture()
|
||||
|
||||
end
|
||||
|
||||
function CanvasElement:parseOrigin(origin, size)
|
||||
if (origin == "center") then
|
||||
return size/2
|
||||
elseif (origin == "end") then
|
||||
return size
|
||||
else
|
||||
return origin or 0
|
||||
end
|
||||
end
|
||||
|
||||
function CanvasElement:draw()
|
||||
love.graphics.setColor(1, 1, 1, self.opacity)
|
||||
local texture = self.canvas.texture
|
||||
if (self.canvas.dual) then
|
||||
texture = self.canvas.final
|
||||
end
|
||||
love.graphics.draw(texture, self.x - self.canvas.padding,self.y - self.canvas.padding,self.r,self.sx,self.sy,self.ox,self.oy)
|
||||
love.graphics.setColor(1, 1, 1, 1)
|
||||
end
|
||||
|
||||
return CanvasElement
|
19
birb/modules/gui/elements/color.lua
Normal file
19
birb/modules/gui/elements/color.lua
Normal file
|
@ -0,0 +1,19 @@
|
|||
local Parent = require "birb.modules.gui.elements.parent"
|
||||
local ColorElement = Parent:extend()
|
||||
|
||||
function ColorElement:new(name, r, g, b, opacity)
|
||||
local w, h = core.screen:getDimensions()
|
||||
ColorElement.super.new(self, name, self.x, self.y, w, h)
|
||||
self.r = r or 1
|
||||
self.g = g or 1
|
||||
self.b = b or 1
|
||||
self.opacity = opacity or 1
|
||||
end
|
||||
|
||||
function ColorElement:draw()
|
||||
love.graphics.setColor(self.r, self.g, self.b, self.opacity)
|
||||
love.graphics.rectangle("fill", 0, 0, self.w, self.h)
|
||||
utils.graphics.resetColor()
|
||||
end
|
||||
|
||||
return ColorElement
|
35
birb/modules/gui/elements/composite.lua
Normal file
35
birb/modules/gui/elements/composite.lua
Normal file
|
@ -0,0 +1,35 @@
|
|||
local Parent = require "birb.modules.gui.elements.parent"
|
||||
local CompositeElement = Parent:extend()
|
||||
|
||||
function CompositeElement:new(name, x, y, childrenList)
|
||||
self.children = {}
|
||||
self:addChildren(childrenList)
|
||||
CompositeElement.super.new(self, name, x, y, 1, 1)
|
||||
self.isVisible = true
|
||||
end
|
||||
|
||||
function CompositeElement:addChildren(list)
|
||||
for _, childData in ipairs(list) do
|
||||
self:addChild(childData[1], childData[2], childData[3])
|
||||
end
|
||||
end
|
||||
|
||||
function CompositeElement:addChild(children, relx, rely)
|
||||
local child = {}
|
||||
child.name = children.name
|
||||
child.relx = relx
|
||||
child.rely = rely
|
||||
table.insert(self.children, child)
|
||||
end
|
||||
|
||||
function CompositeElement:update(dt)
|
||||
for _, child in ipairs(self.children) do
|
||||
local childElement = self.gui.elements[child.name]
|
||||
childElement.x = self.x + child.relx
|
||||
childElement.y = self.y + child.rely
|
||||
childElement.isVisible = self.isVisible
|
||||
childElement.depth = self.depth
|
||||
end
|
||||
end
|
||||
|
||||
return CompositeElement
|
13
birb/modules/gui/elements/counter.lua
Normal file
13
birb/modules/gui/elements/counter.lua
Normal file
|
@ -0,0 +1,13 @@
|
|||
local Parent = require "birb.modules.gui.elements.variable"
|
||||
local CounterElement = Parent:extend()
|
||||
|
||||
function CounterElement:new(name, fontName, object, varName, nbrs, x, y, align)
|
||||
CounterElement.super.new(self, name, fontName, object, varName, x, y, align)
|
||||
self.nbrs = nbrs or 0
|
||||
end
|
||||
|
||||
function CounterElement:getText()
|
||||
return utils.math.numberToString(CounterElement.super.getText(self), self.nbrs)
|
||||
end
|
||||
|
||||
return CounterElement
|
31
birb/modules/gui/elements/drawable.lua
Normal file
31
birb/modules/gui/elements/drawable.lua
Normal file
|
@ -0,0 +1,31 @@
|
|||
local Parent = require "birb.modules.gui.elements.parent"
|
||||
local DrawableElement = Parent:extend()
|
||||
|
||||
function DrawableElement:new(name, drawable, x, y,r,sx,sy,ox,oy, opacity)
|
||||
self.drawable = drawable
|
||||
|
||||
local w, h = self.drawable:getDimensions()
|
||||
DrawableElement.super.new(self, name, x, y, w, h)
|
||||
self.r = r or 0
|
||||
self.sx, self.sy = sx or 1, sy or 1
|
||||
self.ox, self.oy = self:parseOrigin(ox, w), self:parseOrigin(oy, h)
|
||||
self.opacity = opacity or 1
|
||||
end
|
||||
|
||||
function DrawableElement:parseOrigin(origin, size)
|
||||
if (origin == "center") then
|
||||
return size/2
|
||||
elseif (origin == "end") then
|
||||
return size
|
||||
else
|
||||
return origin or 0
|
||||
end
|
||||
end
|
||||
|
||||
function DrawableElement:draw()
|
||||
love.graphics.setColor(1, 1, 1, self.opacity)
|
||||
love.graphics.draw(self.drawable, self.x,self.y,self.r,self.sx,self.sy,self.ox,self.oy)
|
||||
love.graphics.setColor(1, 1, 1, 1)
|
||||
end
|
||||
|
||||
return DrawableElement
|
157
birb/modules/gui/elements/parent.lua
Normal file
157
birb/modules/gui/elements/parent.lua
Normal file
|
@ -0,0 +1,157 @@
|
|||
local Rect = require "birb.classes.2D.rect"
|
||||
local GuiElement = Rect:extend()
|
||||
|
||||
local TweenManager = require "birb.classes.time"
|
||||
|
||||
function GuiElement:new(name, x, y, w, h)
|
||||
GuiElement.super.new(self, x, y, w, h)
|
||||
self.name = name
|
||||
|
||||
self.isVisible = true
|
||||
self.screen = nil
|
||||
|
||||
self.depth = 10
|
||||
|
||||
self.tweens = TweenManager(self)
|
||||
self:initWrapper()
|
||||
|
||||
self:register()
|
||||
end
|
||||
|
||||
function GuiElement:initWrapper()
|
||||
self.scene = core.scenemanager.nextScene or core.scenemanager.currentScene
|
||||
self.gui = self.scene.gui
|
||||
self.assets = self.scene.assets
|
||||
end
|
||||
|
||||
function GuiElement:setKeyPressAction(func)
|
||||
self.func = func
|
||||
end
|
||||
|
||||
function GuiElement:register()
|
||||
self.creationId = self.gui:addElement(self.name, self)
|
||||
end
|
||||
|
||||
function GuiElement:destroy()
|
||||
self.gui:deleteElement(self.name)
|
||||
if (self.screen ~= nil) then
|
||||
self.screen:deleteElement(self.name)
|
||||
end
|
||||
end
|
||||
|
||||
-- VISIBILITY/ACTIVITY
|
||||
-- Handle drawing and how we interact with
|
||||
|
||||
function GuiElement:setDepth(depth)
|
||||
self.depth = depth or 0
|
||||
end
|
||||
|
||||
function GuiElement:getVisibility()
|
||||
if (self.screen ~= nil) then
|
||||
return (self.isVisible and self.screen.isVisible)
|
||||
else
|
||||
return self.isVisible
|
||||
end
|
||||
end
|
||||
|
||||
function GuiElement:setVisibility(visibility)
|
||||
self.isVisible = visibility
|
||||
end
|
||||
|
||||
function GuiElement:getFocus(widgetId, page)
|
||||
self.gui:setFocus(self.name, widgetId, page)
|
||||
end
|
||||
|
||||
function GuiElement:haveFocus()
|
||||
return (self.gui.focusedElement == self.name)
|
||||
end
|
||||
|
||||
function GuiElement:looseFocus()
|
||||
if (self:haveFocus()) then
|
||||
self.gui:removeFocus()
|
||||
end
|
||||
end
|
||||
|
||||
function GuiElement:setSubFocus()
|
||||
-- Useless for basic element
|
||||
end
|
||||
|
||||
function GuiElement:isTransforming()
|
||||
return self.tweens:haveTween()
|
||||
end
|
||||
|
||||
-- UPDATE FUNCTIONS
|
||||
-- Update the menu every game update
|
||||
|
||||
-- External update function
|
||||
function GuiElement:updateElement(dt)
|
||||
self:update(dt)
|
||||
self.tweens:update(dt)
|
||||
end
|
||||
|
||||
-- Internal update function
|
||||
function GuiElement:update(dt)
|
||||
-- Cette fonction ne contient rien par défaut
|
||||
end
|
||||
|
||||
-- TWEEN FUNCTIONS
|
||||
-- Handle tweening
|
||||
|
||||
function GuiElement:newTween(start, duration, target, easing)
|
||||
self.tweens:newTween(start, duration, target, easing)
|
||||
end
|
||||
|
||||
function GuiElement:newMovement(start, duration, x, y, easing)
|
||||
self:newTween(start, duration, {x = x, y = y}, easing)
|
||||
end
|
||||
|
||||
function GuiElement:newSwitch(start, bools)
|
||||
self.tweens:newSwitch(start, bools)
|
||||
end
|
||||
|
||||
function GuiElement:newFunc(start, name, func)
|
||||
self.tweens:newFunc(start, name, func)
|
||||
end
|
||||
|
||||
function GuiElement:delayFocus(start)
|
||||
self.tweens:newFunc(start, "focus", function ()
|
||||
self:getFocus()
|
||||
end)
|
||||
end
|
||||
|
||||
-- DRAW FUNCTIONS
|
||||
-- Draw the menu and its content
|
||||
|
||||
function GuiElement:redraw()
|
||||
|
||||
end
|
||||
|
||||
function GuiElement:drawElement()
|
||||
self:draw()
|
||||
end
|
||||
|
||||
function GuiElement:draw()
|
||||
-- nothing here
|
||||
end
|
||||
|
||||
-- KEYBOARD FUNCTIONS
|
||||
-- Handle key press
|
||||
|
||||
function GuiElement:keypressed(key)
|
||||
if (self.func ~= nil) then
|
||||
self.func(key)
|
||||
end
|
||||
end
|
||||
|
||||
-- MOUSE FUNCTIONS
|
||||
-- Handle pointers (clic/touch)
|
||||
|
||||
function GuiElement:mousemoved(x, y)
|
||||
-- Cette fonction ne contient rien par défaut
|
||||
end
|
||||
|
||||
function GuiElement:mousepressed(x, y, button, istouch)
|
||||
-- Cette fonction ne contient rien par défaut
|
||||
end
|
||||
|
||||
return GuiElement
|
23
birb/modules/gui/elements/text.lua
Normal file
23
birb/modules/gui/elements/text.lua
Normal file
|
@ -0,0 +1,23 @@
|
|||
local Parent = require "birb.modules.gui.elements.parent"
|
||||
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.align = align
|
||||
self.opacity = 1
|
||||
end
|
||||
|
||||
function TextElement:getText()
|
||||
return self.text
|
||||
end
|
||||
|
||||
function TextElement:draw()
|
||||
self.font:setColor(1, 1, 1, self.opacity)
|
||||
self.font:draw(self:getText(), self.x, self.y, -1, self.align)
|
||||
love.graphics.setColor(1, 1, 1, 1)
|
||||
end
|
||||
|
||||
return TextElement
|
19
birb/modules/gui/elements/tile.lua
Normal file
19
birb/modules/gui/elements/tile.lua
Normal file
|
@ -0,0 +1,19 @@
|
|||
local Parent = require "birb.modules.gui.elements.drawable"
|
||||
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]
|
||||
assert(asset ~= nil, assetName .. " ( tileset ) doesn't exist")
|
||||
self.tileId = id
|
||||
|
||||
TileElement.super.new(self, name, asset, x, y,r,sx,sy,ox,oy, opacity)
|
||||
end
|
||||
|
||||
function TileElement:draw()
|
||||
love.graphics.setColor(1, 1, 1, self.opacity)
|
||||
self.drawable:drawTile(self.tileId, self.x,self.y,self.r,self.sx,self.sy,self.ox,self.oy)
|
||||
utils.graphics.resetColor()
|
||||
end
|
||||
|
||||
return TileElement
|
14
birb/modules/gui/elements/variable.lua
Normal file
14
birb/modules/gui/elements/variable.lua
Normal file
|
@ -0,0 +1,14 @@
|
|||
local Parent = require "birb.modules.gui.elements.text"
|
||||
local VariableElement = Parent:extend()
|
||||
|
||||
function VariableElement:new(name, fontName, object, varName, x, y, align)
|
||||
VariableElement.super.new(self, name, fontName, "", x, y, align)
|
||||
self.object = object
|
||||
self.variable = varName
|
||||
end
|
||||
|
||||
function VariableElement:getText()
|
||||
return self.object[self.variable]
|
||||
end
|
||||
|
||||
return VariableElement
|
187
birb/modules/gui/init.lua
Normal file
187
birb/modules/gui/init.lua
Normal file
|
@ -0,0 +1,187 @@
|
|||
-- modules/gui :: a simple gui system, that manage all overhead elements of the game.
|
||||
|
||||
--[[
|
||||
Copyright © 2021 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 Gui = Object:extend()
|
||||
|
||||
local ElementList = require "birb.modules.gui.mixins.elements"
|
||||
local ScreenList = require "birb.modules.gui.mixins.screens"
|
||||
Gui:implement(ScreenList)
|
||||
Gui:implement(ElementList)
|
||||
|
||||
local TransformDataStruct = require "birb.structures.tween"
|
||||
|
||||
function Gui:new(scene)
|
||||
self.scene = scene
|
||||
self:reset()
|
||||
self.sfx = {}
|
||||
end
|
||||
|
||||
function Gui:reset()
|
||||
self:initElements()
|
||||
self:initScreens()
|
||||
end
|
||||
|
||||
function Gui:update(dt)
|
||||
for _, element in pairs(self.elements) do
|
||||
if (element ~= nil) then
|
||||
element:updateElement(dt)
|
||||
end
|
||||
end
|
||||
for _, screen in pairs(self.screens) do
|
||||
if (screen ~= nil) then
|
||||
screen:update(dt)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- TWEEN FUNCTIONS
|
||||
-- Handle tweening
|
||||
|
||||
function Gui:transform(data, delay)
|
||||
delay = delay or 0
|
||||
|
||||
local time = 0
|
||||
for _, rawTransform in ipairs(data) do
|
||||
local newTime = self:transformOne(rawTransform, delay)
|
||||
time = math.max(time, newTime)
|
||||
end
|
||||
return time
|
||||
end
|
||||
|
||||
function Gui:playScreenTransform(screenname, name, delay)
|
||||
return self.screens[screenname]:playTransform(name, delay)
|
||||
end
|
||||
|
||||
function Gui:transformOne(rawTransform, delay)
|
||||
delay = delay or 0
|
||||
|
||||
local struct = TransformDataStruct[rawTransform[2]]
|
||||
assert(struct ~= nil, "Structure " .. rawTransform[1] .. " doesn't exists ")
|
||||
local transform = utils.table.parse(rawTransform, struct, 0)
|
||||
|
||||
local time = transform.start + delay
|
||||
|
||||
if transform.type == "tween" then
|
||||
self:newTween(transform.name, time, transform.duration, transform.target, transform.easing)
|
||||
elseif transform.type == "movement" then
|
||||
self:newMovement(transform.name, time, transform.duration, transform.x, transform.y, transform.easing)
|
||||
elseif transform.type == "switch" then
|
||||
self:newSwitch(transform.name, time, transform.bools)
|
||||
elseif transform.type == "delayFocus" then
|
||||
self:delayFocus(transform.name, time)
|
||||
end
|
||||
|
||||
if (transform.duration ~= nil) then
|
||||
time = time + transform.duration
|
||||
end
|
||||
return time
|
||||
end
|
||||
|
||||
function Gui:newTween(element, start, duration, target, easing)
|
||||
assert(self.elements[element] ~= nil, element .. " does not exists")
|
||||
self.elements[element]:newTween(start, duration, target, easing)
|
||||
end
|
||||
|
||||
function Gui:newMovement(element, start, duration, x, y, easing)
|
||||
assert(self.elements[element] ~= nil, element .. " does not exists")
|
||||
self.elements[element]:newMovement(start, duration, x, y, easing)
|
||||
end
|
||||
|
||||
function Gui:newSwitch(element, start, bools)
|
||||
assert(self.elements[element] ~= nil, element .. " does not exists")
|
||||
self.elements[element]:newSwitch(start, bools)
|
||||
end
|
||||
|
||||
function Gui:delayFocus(element, start)
|
||||
assert(self.elements[element] ~= nil, element .. " does not exists")
|
||||
self.elements[element]:delayFocus(start)
|
||||
end
|
||||
|
||||
function Gui:hideScreen(screenname)
|
||||
self.screens[screenname]:hide()
|
||||
end
|
||||
|
||||
|
||||
function Gui:showScreen(screenname, focusElement, widgetId, page, arbitraryDatas)
|
||||
self.screens[screenname]:show(focusElement, widgetId, page)
|
||||
self.screens[screenname]:setDatas(arbitraryDatas)
|
||||
end
|
||||
|
||||
-- SOUND FUNCTIONS
|
||||
-- Handle SFX
|
||||
|
||||
function Gui:addSFX(guiName, sfxName)
|
||||
self.sfx[guiName] = sfxName
|
||||
end
|
||||
|
||||
function Gui:playSFX(type)
|
||||
local sfxName = self.sfx[type]
|
||||
if (sfxName ~= nil) then
|
||||
local sfx = self.scene.assets.sfx[sfxName]
|
||||
if (sfx ~= nil) then
|
||||
sfx:play()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- KEYBOARD FUNCTIONS
|
||||
-- Handle keyboard
|
||||
|
||||
function Gui:keycheck(keys)
|
||||
local haveFocus = self:haveFocus()
|
||||
if (haveFocus) then
|
||||
local elem = self:getFocusedElement()
|
||||
for key,_ in pairs(keys) do
|
||||
if (keys[key].isPressed and not elem:isTransforming()) then
|
||||
elem:keypressed(key)
|
||||
end
|
||||
end
|
||||
end
|
||||
return haveFocus
|
||||
end
|
||||
|
||||
-- DRAW FUNCTIONS
|
||||
-- Draw the menu and its content
|
||||
|
||||
function Gui:redraw()
|
||||
for _, element in pairs(self:getVisibleElement(true)) do
|
||||
element:redraw()
|
||||
end
|
||||
for _, element in pairs(self:getVisibleElement(false)) do
|
||||
element:redraw()
|
||||
end
|
||||
end
|
||||
|
||||
function Gui:drawTop()
|
||||
for _, element in ipairs(self:getVisibleElement(true)) do
|
||||
element:drawElement()
|
||||
end
|
||||
end
|
||||
|
||||
function Gui:drawBottom()
|
||||
for _, element in ipairs(self:getVisibleElement(false)) do
|
||||
element:drawElement()
|
||||
end
|
||||
end
|
||||
|
||||
return Gui
|
|
@ -31,9 +31,9 @@ local View2D = require(cwd .. "views.view2D")
|
|||
-- INIT FUNCTIONS
|
||||
-- Initialize and configure the flowbox
|
||||
|
||||
function FlowBox:new(menusystem, name, x, y, w, h, slots_hor, slots_vert)
|
||||
function FlowBox:new(name, x, y, w, h, slots_hor, slots_vert)
|
||||
self.view = View2D(slots_hor, slots_vert)
|
||||
FlowBox.super.new(self, menusystem, name, x, y, w, h)
|
||||
FlowBox.super.new(self, name, x, y, w, h)
|
||||
self:setRealSize()
|
||||
end
|
||||
|
||||
|
@ -85,18 +85,22 @@ function FlowBox:moveByKeys(key)
|
|||
local col, line = self.view:getCoord(self.widget:getSelected())
|
||||
if key == 'left' then
|
||||
self:moveCursor2D(col - 1, line)
|
||||
self:playNavigationSound()
|
||||
end
|
||||
|
||||
if key == 'right' then
|
||||
self:moveCursor2D(col + 1, line)
|
||||
self:playNavigationSound()
|
||||
end
|
||||
|
||||
if key == 'up' then
|
||||
self:moveCursor2D(col, line - 1)
|
||||
self:playNavigationSound()
|
||||
end
|
||||
|
||||
if key == 'down' then
|
||||
self:moveCursor2D(col, line + 1)
|
||||
self:playNavigationSound()
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -112,10 +116,10 @@ end
|
|||
-- DRAW FUNCTIONS
|
||||
-- Draw the menu and its content
|
||||
|
||||
function FlowBox:draw()
|
||||
function FlowBox:drawTexture()
|
||||
self.view:updateFirstSlot(self.widget:getSelected())
|
||||
local widgety = self.y
|
||||
local widgetx = self.x
|
||||
local widgety = self.canvas.padding
|
||||
local widgetx = self.canvas.padding
|
||||
|
||||
local listWidget = self.widget:getList(self.view.firstSlot, self.view.slotNumber)
|
||||
|
||||
|
@ -138,7 +142,7 @@ function FlowBox:getGraphicalCursorPosition()
|
|||
local col, line = self.view:getCoord(self.widget:getSelected())
|
||||
local x = (col) * h
|
||||
local y = (line - beginline) * h
|
||||
return self.x + x, self.y + y, w, h
|
||||
return x, y, w, h
|
||||
end
|
||||
|
||||
return FlowBox
|
|
@ -26,14 +26,14 @@ local cwd = (...):gsub('%.grid$', '') .. "."
|
|||
local Menu = require(cwd .. "parent")
|
||||
local GridBox = Menu:extend()
|
||||
|
||||
local View2D = require "birb.modules.menusystem.menus.views.view2D"
|
||||
local View2D = require "birb.modules.gui.menus.views.view2D"
|
||||
|
||||
-- INIT FUNCTIONS
|
||||
-- Initialize and configure the menu
|
||||
|
||||
function GridBox:new(menusystem, name, x, y, w, h, colNumber, lineNumber)
|
||||
function GridBox:new(name, x, y, w, h, colNumber, lineNumber)
|
||||
self.view = View2D(colNumber, lineNumber)
|
||||
GridBox.super.new(self, menusystem, name, x, y, w, h)
|
||||
GridBox.super.new(self, name, x, y, w, h)
|
||||
self.h = lineNumber * self.widgetSize.h -- On fait en sorte que la hauteur
|
||||
self.w = colNumber * self.widgetSize.w -- et la largeur
|
||||
-- soit un multiple du nombre de slot et de leur dimensions
|
||||
|
@ -150,18 +150,22 @@ function GridBox:keyreleased(key, code)
|
|||
local col, line = self.cursor.x, self.cursor.y
|
||||
if key == 'left' then
|
||||
self:moveCol(-1)
|
||||
self:playNavigationSound()
|
||||
end
|
||||
|
||||
if key == 'right' then
|
||||
self:moveCol(1)
|
||||
self:playNavigationSound()
|
||||
end
|
||||
|
||||
if key == 'up' then
|
||||
self:moveLine(-1)
|
||||
self:playNavigationSound()
|
||||
end
|
||||
|
||||
if key == 'down' then
|
||||
self:moveLine(1)
|
||||
self:playNavigationSound()
|
||||
end
|
||||
|
||||
if key == "A" and self.widget:getSelected() <= self.widget:lenght() then
|
||||
|
@ -247,12 +251,12 @@ end
|
|||
-- DRAW FUNCTIONS
|
||||
-- Draw the menu and its content
|
||||
|
||||
function GridBox:draw()
|
||||
function GridBox:drawTexture()
|
||||
|
||||
for i,v in ipairs(self.slots) do
|
||||
if self:haveWidget(i) then
|
||||
local widgetx = self.x + (v.x * self.widgetSize.w)
|
||||
local widgety = self.y + (v.y * self.widgetSize.h)
|
||||
local widgetx = self.canvas.padding + (v.x * self.widgetSize.w)
|
||||
local widgety = self.canvas.padding + (v.y * self.widgetSize.h)
|
||||
if self.widget:getSelected() == v.widgetID and self:haveFocus() == true then
|
||||
self.widget.list[v.widgetID]:drawSelected(widgetx, widgety)
|
||||
else
|
||||
|
@ -269,7 +273,7 @@ function GridBox:drawCursor()
|
|||
local w, h = self:getWidgetSize(slot)
|
||||
local x = self.slots[slot].x * self.widgetSize.w
|
||||
local y = self.slots[slot].y * self.widgetSize.h
|
||||
self:drawGraphicalCursor(self.x + x, self.y + y, w, h)
|
||||
self:drawGraphicalCursor(x, y, w, h)
|
||||
end
|
||||
end
|
||||
|
|
@ -31,9 +31,9 @@ local View1D = require(cwd .. "views.view1D")
|
|||
-- INIT FUNCTIONS
|
||||
-- Initialize and configure functions.
|
||||
|
||||
function HListBox:new(menusystem, name, x, y, w, h, slotNumber)
|
||||
function HListBox:new(name, x, y, w, h, slotNumber)
|
||||
self.view = View1D(slotNumber)
|
||||
HListBox.super.new(self, menusystem, name, x, y, w, h)
|
||||
HListBox.super.new(self, name, x, y, w, h)
|
||||
self.w = slotNumber * self.widgetSize.w -- On fait en sorte que la hauteur
|
||||
-- soit un multiple du nombre de slot et de leur hauteur
|
||||
end
|
||||
|
@ -60,10 +60,14 @@ end
|
|||
function HListBox:moveByKeys(key, code)
|
||||
if key == 'left' then
|
||||
self.widget:moveCursor(-1)
|
||||
self.canvas.needRedraw = true
|
||||
self:playNavigationSound()
|
||||
end
|
||||
|
||||
if key == 'right' then
|
||||
self.widget:moveCursor(1)
|
||||
self.canvas.needRedraw = true
|
||||
self:playNavigationSound()
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -77,15 +81,15 @@ end
|
|||
-- DRAW FUNCTIONS
|
||||
-- Draw the menu and its content
|
||||
|
||||
function HListBox:draw()
|
||||
function HListBox:drawTexture()
|
||||
self.view:updateFirstSlot(self.widget:getSelected())
|
||||
|
||||
local widgetx = self.x
|
||||
local widgetx = self.canvas.padding
|
||||
|
||||
local listWidget = self.widget:getList(self.view.firstSlot, self.view.slotNumber)
|
||||
|
||||
for _, widget in ipairs(listWidget) do
|
||||
widget:drawWidget(widgetx, self.y, self.widgetSize.w, self.h)
|
||||
widget:drawWidget(widgetx, self.canvas.padding, self.widgetSize.w, self.h)
|
||||
widgetx = widgetx + self.widgetSize.w
|
||||
end
|
||||
end
|
||||
|
@ -95,7 +99,7 @@ function HListBox:getGraphicalCursorPosition()
|
|||
local w, h = self:getWidgetSize()
|
||||
local x = (self.widget:getSelected() - self.view.firstSlot) * w
|
||||
|
||||
return self.x + x,self.y, w, h
|
||||
return x, 0, w, h
|
||||
end
|
||||
|
||||
return HListBox
|
|
@ -31,11 +31,13 @@ local View1D = require(cwd .. "views.view1D")
|
|||
-- INIT FUNCTIONS
|
||||
-- Initialize and configure functions.
|
||||
|
||||
function ListBox:new(menusystem, name, x, y, w, h, slotNumber)
|
||||
function ListBox:new(name, x, y, w, h, slotNumber)
|
||||
self.view = View1D(slotNumber)
|
||||
ListBox.super.new(self, menusystem, name, x, y, w, h)
|
||||
ListBox.super.new(self, name, x, y, w, h)
|
||||
self.h = slotNumber * self.widgetSize.h -- On fait en sorte que la hauteur
|
||||
-- soit un multiple du nombre de slot et de leur hauteur
|
||||
self.lateralFunc = nil
|
||||
self.packAtEnd = false
|
||||
end
|
||||
|
||||
-- UPDATE FUNCTIONS
|
||||
|
@ -54,16 +56,28 @@ function ListBox:resetView()
|
|||
self.view:reset()
|
||||
end
|
||||
|
||||
function ListBox:addLateralAction(func)
|
||||
self.lateralFunc = func
|
||||
end
|
||||
|
||||
-- KEYBOARD FUNCTIONS
|
||||
-- Handle input from keyboard/controllers.
|
||||
|
||||
function ListBox:moveByKeys(key)
|
||||
if key == 'up' then
|
||||
self.widget:moveCursor(-1)
|
||||
self:playNavigationSound()
|
||||
self.canvas.needRedraw = true
|
||||
end
|
||||
|
||||
if key == 'down' then
|
||||
self.widget:moveCursor(1)
|
||||
self:playNavigationSound()
|
||||
self.canvas.needRedraw = true
|
||||
end
|
||||
|
||||
if (self.lateralFunc ~= nil and (key == 'left' or key == 'right')) then
|
||||
self.widget:lateralAction(self.lateralFunc, key)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -77,24 +91,26 @@ end
|
|||
-- DRAW FUNCTIONS
|
||||
-- draw the menu and the rest of content.
|
||||
|
||||
function ListBox:draw()
|
||||
self.view:updateFirstSlot(self.widget:getSelected())
|
||||
local widgety = self.y
|
||||
function ListBox:getListPart(relativeNumber)
|
||||
if (self.packAtEnd) then relativeNumber = relativeNumber + math.max(0, self.view.slotNumber - self.widget:lenght()) end
|
||||
return 0, (relativeNumber) * self.widgetSize.h, self.w, self.widgetSize.h
|
||||
end
|
||||
|
||||
function ListBox:drawTexture()
|
||||
self.view:updateFirstSlot(self.widget:getSelected())
|
||||
local listWidget = self.widget:getList(self.view.firstSlot, self.view.slotNumber)
|
||||
|
||||
for _, widget in ipairs(listWidget) do
|
||||
widget:drawWidget(self.x, widgety, self.w, self.widgetSize.h)
|
||||
widgety = widgety + self.widgetSize.h
|
||||
for i, widget in ipairs(listWidget) do
|
||||
local x, y, w, h = self:getListPart(i - 1)
|
||||
self:drawWidgetBackground(x + self.canvas.padding, y + self.canvas.padding, w, h)
|
||||
widget:drawWidget(x + self.canvas.padding, y + self.canvas.padding, w, h)
|
||||
end
|
||||
end
|
||||
|
||||
function ListBox:getGraphicalCursorPosition()
|
||||
self.view:updateFirstSlot(self.widget:getSelected())
|
||||
local w, h = self:getWidgetSize()
|
||||
local y = (self.widget:getSelected() - self.view.firstSlot) * h
|
||||
local x, y, w, h = self:getListPart(self.widget:getSelected() - self.view.firstSlot)
|
||||
|
||||
return self.x,self.y + y, w, h
|
||||
return self:getListPart(self.widget:getSelected() - self.view.firstSlot)
|
||||
end
|
||||
|
||||
return ListBox
|
|
@ -1,5 +1,5 @@
|
|||
local MenuModel = Object:extend()
|
||||
local Page = require "birb.modules.menusystem.menus.model.page"
|
||||
local Page = require "birb.modules.gui.menus.model.page"
|
||||
|
||||
local function updateWidgetByOrder(a, b)
|
||||
if a.order ~= b.order then
|
||||
|
@ -21,6 +21,7 @@ function MenuModel:new()
|
|||
self.cancel = 0
|
||||
self.limit = -1
|
||||
-- self:updateWidgetSize()
|
||||
self.hoverFunc = nil
|
||||
end
|
||||
|
||||
function MenuModel:clear()
|
||||
|
@ -33,6 +34,7 @@ end
|
|||
|
||||
function MenuModel:addPage(pageName)
|
||||
local page = Page()
|
||||
page.name = pageName
|
||||
self.pages[pageName] = page
|
||||
self.currentPage = pageName
|
||||
return page
|
||||
|
@ -58,6 +60,7 @@ end
|
|||
function MenuModel:switch(pageName)
|
||||
if (self:pageExists(pageName)) then
|
||||
self.currentPage = pageName
|
||||
self:hoverAction()
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -70,6 +73,10 @@ function MenuModel:getCurrentPage()
|
|||
return self:getPage(self.currentPage)
|
||||
end
|
||||
|
||||
function MenuModel:getCurrentPageName()
|
||||
return self.currentPage
|
||||
end
|
||||
|
||||
-- UPDATE/DRAW FUNCTIONS
|
||||
-- All the update functions
|
||||
|
||||
|
@ -91,6 +98,10 @@ end
|
|||
-- ACTION FUNCTIONS
|
||||
-- All the actions callback used by the widgets
|
||||
|
||||
function MenuModel:addHoverAction(func)
|
||||
self.hoverFunc = func
|
||||
end
|
||||
|
||||
function MenuModel:cancelAction()
|
||||
local page = self:getCurrentPage()
|
||||
page:cancelAction()
|
||||
|
@ -106,6 +117,19 @@ function MenuModel:selectedAction()
|
|||
page:selectedAction()
|
||||
end
|
||||
|
||||
function MenuModel:hoverAction()
|
||||
local page = self:getCurrentPage()
|
||||
if (self.hoverFunc ~= nil) then
|
||||
page:hoverAction(self.hoverFunc)
|
||||
end
|
||||
end
|
||||
|
||||
function MenuModel:lateralAction(func, key)
|
||||
local page = self:getCurrentPage()
|
||||
page:lateralAction(func, key)
|
||||
end
|
||||
|
||||
|
||||
-- WIDGET FUNCTIONS
|
||||
-- All the functions to handle widgets
|
||||
|
||||
|
@ -142,9 +166,9 @@ end
|
|||
-- CANCEL FUNCTIONS
|
||||
-- Add a widget as a "cancel" function
|
||||
|
||||
function MenuModel:setCancelWidget()
|
||||
function MenuModel:setCancelWidget(id)
|
||||
local page = self:getCurrentPage()
|
||||
page:setCancelWidget()
|
||||
page:setCancelWidget(id)
|
||||
end
|
||||
|
||||
function MenuModel:getCancelWidget()
|
||||
|
@ -167,22 +191,36 @@ end
|
|||
|
||||
function MenuModel:trySelectWidget(cursorid)
|
||||
local page = self:getCurrentPage()
|
||||
return page:trySelectWidget(cursorid)
|
||||
local isSuccess = page:trySelectWidget(cursorid)
|
||||
if (isSuccess) then
|
||||
self:hoverAction()
|
||||
end
|
||||
return isSuccess
|
||||
end
|
||||
|
||||
function MenuModel:setCursor(cursorid)
|
||||
local page = self:getCurrentPage()
|
||||
page:setCursor(cursorid)
|
||||
self:hoverAction()
|
||||
end
|
||||
|
||||
function MenuModel:moveCursorAbsolute(newSelected)
|
||||
local page = self:getCurrentPage()
|
||||
page:moveCursorAbsolute(newSelected)
|
||||
self:hoverAction()
|
||||
end
|
||||
|
||||
function MenuModel:moveCursor(relative)
|
||||
local page = self:getCurrentPage()
|
||||
page:moveCursor(relative)
|
||||
self:hoverAction()
|
||||
end
|
||||
|
||||
-- DRAW
|
||||
-- Draw widget
|
||||
function MenuModel:redraw()
|
||||
local page = self:getCurrentPage()
|
||||
page:redraw()
|
||||
end
|
||||
|
||||
|
|
@ -66,14 +66,15 @@ end
|
|||
-- All the actions callback used by the widgets
|
||||
|
||||
function Page:cancelAction()
|
||||
if (self.cancel ~= 0) then
|
||||
self:action(self.cancel, "key")
|
||||
if (self:getCancelWidget() ~= 0) then
|
||||
self:action(self:getCancelWidget(), "key")
|
||||
end
|
||||
end
|
||||
|
||||
function Page:action(id, type)
|
||||
if (self:widgetExist(id)) then
|
||||
self.widgets[id]:action(type)
|
||||
self.widgets[id]:playSFX()
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -83,6 +84,18 @@ function Page:selectedAction()
|
|||
end
|
||||
end
|
||||
|
||||
function Page:hoverAction(func)
|
||||
if (self:widgetExist(self.selected)) then
|
||||
func(self.widgets[self.selected])
|
||||
end
|
||||
end
|
||||
|
||||
function Page:lateralAction(func, key)
|
||||
if (self:widgetExist(self.selected)) then
|
||||
func(key, self.widgets[self.selected], self.selected, self.name)
|
||||
end
|
||||
end
|
||||
|
||||
-- WIDGET FUNCTIONS
|
||||
-- All the functions to handle widgets
|
||||
|
||||
|
@ -133,11 +146,18 @@ end
|
|||
-- Add a widget as a "cancel" function
|
||||
|
||||
function Page:setCancelWidget(id)
|
||||
self.cancel = #self.widgets
|
||||
if (id == nil) then
|
||||
id = #self.widgets
|
||||
end
|
||||
self.cancel = id
|
||||
end
|
||||
|
||||
function Page:getCancelWidget(id)
|
||||
function Page:getCancelWidget()
|
||||
if (self.cancel == "last") then
|
||||
return #self.widgets
|
||||
else
|
||||
return self.cancel
|
||||
end
|
||||
end
|
||||
|
||||
-- CURSOR FUNCTIONS
|
||||
|
@ -181,5 +201,11 @@ function Page:moveCursor(relative)
|
|||
self:moveCursorAbsolute(self.selected + relative)
|
||||
end
|
||||
|
||||
-- DRAW
|
||||
function Page:redraw()
|
||||
for _, widget in ipairs(self.widgets) do
|
||||
widget:redraw()
|
||||
end
|
||||
end
|
||||
|
||||
return Page
|
|
@ -21,30 +21,46 @@
|
|||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
]]
|
||||
|
||||
local GuiElement = require "birb.modules.menusystem.parent"
|
||||
local GuiElement = require "birb.modules.gui.elements.canvas"
|
||||
|
||||
local Menu = GuiElement:extend()
|
||||
local MenuModel = require "birb.modules.menusystem.menus.model"
|
||||
local MenuModel = require "birb.modules.gui.menus.model"
|
||||
|
||||
local menuUtils = require "birb.modules.gui.utils"
|
||||
|
||||
local menuUtils = require "birb.modules.menusystem.utils"
|
||||
-- INIT FUNCTIONS
|
||||
-- Initialize and configure functions.
|
||||
|
||||
function Menu:new(menusystem, name, x, y, w, h)
|
||||
function Menu:new(name, x, y, w, h)
|
||||
Menu.super.new(self, name, x, y, w, h)
|
||||
self.menusystem = self:getGui()
|
||||
|
||||
--TODO: remove this
|
||||
self.menusystem = self.gui
|
||||
|
||||
self.widget = MenuModel()
|
||||
self.widgetSize = {}
|
||||
self:updateWidgetSize()
|
||||
|
||||
self:resetSound()
|
||||
self:initCanvas()
|
||||
self.cancelFunc = nil
|
||||
self.canvas.dual = true
|
||||
end
|
||||
|
||||
-- FUNCTIONS FUNCTIONS
|
||||
-- Add functions to the menu system
|
||||
|
||||
function Menu:addCancelAction(func)
|
||||
self.cancelFunc = func
|
||||
end
|
||||
|
||||
function Menu:addHoverAction(func)
|
||||
self.widget:addHoverAction(func)
|
||||
end
|
||||
|
||||
-- INTERACTION FUNCTIONS
|
||||
-- Keyboard and mouse
|
||||
|
||||
function Menu:keyreleased(key)
|
||||
function Menu:keypressed(key)
|
||||
self:moveByKeys(key)
|
||||
self:actionAndCancel(key)
|
||||
end
|
||||
|
@ -77,10 +93,12 @@ end
|
|||
function Menu:actionAndCancel(key)
|
||||
if key == "A" then
|
||||
self.widget:selectedAction()
|
||||
self.canvas.needRedraw = true
|
||||
end
|
||||
|
||||
if key == "B" then
|
||||
self.widget:cancelAction()
|
||||
self:cancelAction()
|
||||
self.canvas.needRedraw = true
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -107,21 +125,38 @@ function Menu:getPage(pageName)
|
|||
self.widget:getPage(pageName)
|
||||
end
|
||||
|
||||
function Menu:getCurrentPageName()
|
||||
return self.widget:getCurrentPageName()
|
||||
end
|
||||
|
||||
function Menu:switch(pageName)
|
||||
self.widget:switch(pageName)
|
||||
self:resetView()
|
||||
self.canvas.needRedraw = true
|
||||
end
|
||||
|
||||
function Menu:back()
|
||||
self.widget:back()
|
||||
self:resetView()
|
||||
self.canvas.needRedraw = true
|
||||
end
|
||||
|
||||
function GuiElement:setSubFocus(widgetId, pageName)
|
||||
if (pageName ~= nil) then
|
||||
self.widget:switch(pageName)
|
||||
end
|
||||
self.widget:trySelectWidget(widgetId)
|
||||
end
|
||||
|
||||
-- ACTION FUNCTIONS
|
||||
-- Send actions to the widgets
|
||||
|
||||
function Menu:cancelAction()
|
||||
if (self.cancelFunc ~= nil) then
|
||||
self.cancelFunc(self)
|
||||
else
|
||||
self.widget:cancelAction()
|
||||
end
|
||||
end
|
||||
|
||||
function Menu:clear()
|
||||
|
@ -137,8 +172,8 @@ end
|
|||
-- UPDATE FUNCTIONS
|
||||
|
||||
function Menu:updateElement(dt)
|
||||
self:update(dt)
|
||||
self.widget:update(dt)
|
||||
Menu.super.updateElement(self, dt)
|
||||
end
|
||||
|
||||
-- DRAW FUNCTIONS
|
||||
|
@ -146,9 +181,12 @@ end
|
|||
|
||||
function Menu:drawElement()
|
||||
self:draw()
|
||||
end
|
||||
|
||||
function Menu:drawFinalTexture()
|
||||
if (self:haveFocus()) then
|
||||
local x, y, w, h = self:getGraphicalCursorPosition()
|
||||
self:drawGraphicalCursor(x, y, w, h)
|
||||
self:drawGraphicalCursor(self.canvas.padding + x, self.canvas.padding + y, w, h)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -160,11 +198,21 @@ function Menu:drawCanvas()
|
|||
|
||||
end
|
||||
|
||||
function Menu:drawWidgetBackground(x, y, w, h)
|
||||
|
||||
end
|
||||
|
||||
function Menu:redraw()
|
||||
self.widget:redraw()
|
||||
Menu.super.redraw(self)
|
||||
end
|
||||
|
||||
-- WIDGET FUNCTIONS
|
||||
-- Handle widgets of the functions
|
||||
|
||||
function Menu:addWidget(newwidget)
|
||||
self.widget:addWidget(newwidget)
|
||||
self.canvas.needRedraw = true
|
||||
end
|
||||
|
||||
function Menu:setCancelWidget(id)
|
||||
|
@ -193,35 +241,23 @@ end
|
|||
|
||||
function Menu:setCursor(cursorid)
|
||||
self.widget:setCursor(cursorid)
|
||||
self.canvas.needRedraw = true
|
||||
end
|
||||
|
||||
function Menu:moveCursor(new_selected)
|
||||
self:playNavigationSound()
|
||||
self.widget:moveCursorAbsolute(new_selected)
|
||||
self.canvas.needRedraw = true
|
||||
end
|
||||
|
||||
-- SOUND FUNCTION
|
||||
-- Handle SFX
|
||||
|
||||
function Menu:resetSound()
|
||||
self.sound = {}
|
||||
self.sound.active = false
|
||||
self.sound.asset = nil
|
||||
end
|
||||
|
||||
function Menu:setSoundFromSceneAssets(name)
|
||||
self:setSound(self.menusystem.scene.assets:getWithType(name, "sfx"))
|
||||
end
|
||||
|
||||
function Menu:setSound(soundasset)
|
||||
self.sound.active = true
|
||||
self.sound.asset = soundasset
|
||||
end
|
||||
|
||||
function Menu:playNavigationSound()
|
||||
if self.sound.active == true then
|
||||
self.sound.asset:play()
|
||||
end
|
||||
self:playSFX("navigate")
|
||||
end
|
||||
|
||||
function Menu:playSFX(name)
|
||||
self.gui:playSFX(name)
|
||||
end
|
||||
|
||||
-- VIEW FUNCTIONS
|
|
@ -31,7 +31,6 @@ end
|
|||
|
||||
function View1D:reset()
|
||||
self.firstSlot = 1
|
||||
print("reset")
|
||||
end
|
||||
|
||||
function View1D:updateFirstSlot(widgetID)
|
|
@ -21,7 +21,7 @@
|
|||
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 View1D = require "birb.modules.menusystem.menus.views.view1D"
|
||||
local View1D = require "birb.modules.gui.menus.views.view1D"
|
||||
local View2D = View1D:extend()
|
||||
|
||||
function View2D:new(colNumber, lineNumber)
|
|
@ -26,8 +26,8 @@ local BaseWidget = Object:extend()
|
|||
-- Initialize and configure the widget
|
||||
|
||||
function BaseWidget:new(menuName)
|
||||
self:initWrapper()
|
||||
self.menu = self:getMenuByName(menuName)
|
||||
self.assets = self:getAssets()
|
||||
|
||||
self.destroyed = false
|
||||
self.selectable = false
|
||||
|
@ -37,23 +37,35 @@ function BaseWidget:new(menuName)
|
|||
self.canvas = {}
|
||||
self.canvas.texture = nil
|
||||
self.canvas.needRedraw = true
|
||||
self.canvas.isAnimated = false
|
||||
|
||||
self.order = 0
|
||||
self:register()
|
||||
self.func = nil
|
||||
self.type = "select"
|
||||
end
|
||||
|
||||
function BaseWidget:initWrapper()
|
||||
self.scene = core.scenemanager.nextScene or core.scenemanager.currentScene
|
||||
self.gui = self.scene.gui
|
||||
self.assets = self.scene.assets
|
||||
end
|
||||
|
||||
function BaseWidget:setFunc(func)
|
||||
self.func = func
|
||||
end
|
||||
|
||||
function BaseWidget:getMenuByName(name)
|
||||
local gui = self:getGui()
|
||||
return gui:getMenu(name)
|
||||
assert(name ~= nil, "Name cant be nil")
|
||||
return self.gui.elements[name]
|
||||
end
|
||||
|
||||
function BaseWidget:getGui()
|
||||
local scene = core.scenemanager.currentScene
|
||||
return scene.menusystem
|
||||
function BaseWidget:getScene()
|
||||
return core.scenemanager.nextScene or core.scenemanager.currentScene
|
||||
end
|
||||
|
||||
function BaseWidget:getAssets()
|
||||
local scene = core.scenemanager.currentScene
|
||||
local scene = core.scenemanager.nextScene or core.scenemanager.currentScene
|
||||
return scene.assets
|
||||
end
|
||||
|
||||
|
@ -62,7 +74,13 @@ function BaseWidget:register()
|
|||
self.menu:addWidget(self)
|
||||
end
|
||||
|
||||
function BaseWidget:redrawCanvas()
|
||||
function BaseWidget:redraw()
|
||||
if (self.canvas.needRedraw or self.canvas.isAnimated) then
|
||||
self:generateTexture()
|
||||
end
|
||||
end
|
||||
|
||||
function BaseWidget:generateTexture()
|
||||
self.width, self.height = self.menu:getWidgetSize(self.id)
|
||||
|
||||
local canvas = love.graphics.newCanvas(self.width, self.height)
|
||||
|
@ -123,9 +141,6 @@ end
|
|||
-- Update the widget
|
||||
|
||||
function BaseWidget:update(dt)
|
||||
if (self.canvas.needRedraw) then
|
||||
self:redrawCanvas()
|
||||
end
|
||||
-- N/A
|
||||
end
|
||||
|
||||
|
@ -139,8 +154,14 @@ end
|
|||
-- ACTION FUNCTION
|
||||
-- Functions to handle actions and selection.
|
||||
|
||||
function BaseWidget:playSFX()
|
||||
self.menu:playSFX(self.type)
|
||||
end
|
||||
|
||||
function BaseWidget:action(source)
|
||||
--self:destroy()
|
||||
if (self.func ~= nil) then
|
||||
self.func(self)
|
||||
end
|
||||
end
|
||||
|
||||
function BaseWidget:destroy()
|
|
@ -24,7 +24,7 @@
|
|||
local Widget = {}
|
||||
|
||||
-- Add the widget as subvariable to the returned table
|
||||
Widget.Base = require "birb.modules.menusystem.menus.widgets.base"
|
||||
Widget.Text = require "birb.modules.menusystem.menus.widgets.text"
|
||||
Widget.Base = require "birb.modules.gui.menus.widgets.base"
|
||||
Widget.Text = require "birb.modules.gui.menus.widgets.text"
|
||||
|
||||
return Widget
|
|
@ -20,7 +20,7 @@
|
|||
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 BaseWidget = require "birb.modules.menusystem.menus.widgets.base"
|
||||
local BaseWidget = require "birb.modules.gui.menus.widgets.base"
|
||||
local TextWidget = BaseWidget:extend()
|
||||
|
||||
-- TEXT WIDGET
|
||||
|
@ -35,13 +35,14 @@ function TextWidget:new(menuName, font, label, position, padding)
|
|||
-- We add the first label
|
||||
local position = position or "center"
|
||||
self:addLabel(label, position)
|
||||
self:setSelectedColor(1, 1, 1)
|
||||
self:setColor(1, 1, 1)
|
||||
end
|
||||
|
||||
function TextWidget:addLabel(label, position)
|
||||
local complexLabel = {}
|
||||
assert(label ~= nil, "Label can't be nil")
|
||||
complexLabel.label = label
|
||||
complexLabel.position = position
|
||||
complexLabel.position = position or "left"
|
||||
table.insert(self.labels, complexLabel)
|
||||
end
|
||||
|
||||
|
@ -49,6 +50,13 @@ function TextWidget:replaceLabel(id, newLabel)
|
|||
self.labels[id].label = newLabel
|
||||
end
|
||||
|
||||
function TextWidget:setColor(r, g, b)
|
||||
self.color = {}
|
||||
self.color.r = r
|
||||
self.color.g = g
|
||||
self.color.b = b
|
||||
end
|
||||
|
||||
function TextWidget:setSelectedColor(r, g, b)
|
||||
self.selectedColor = {}
|
||||
self.selectedColor.r = r
|
||||
|
@ -61,13 +69,29 @@ function TextWidget:getFont()
|
|||
end
|
||||
|
||||
function TextWidget:getSelectedColor()
|
||||
if (self.selectedColor ~= nil) then
|
||||
return self.selectedColor.r, self.selectedColor.g, self.selectedColor.b
|
||||
else
|
||||
return self:getColor()
|
||||
end
|
||||
end
|
||||
|
||||
function TextWidget:getColor()
|
||||
return self.color.r, self.color.g, self.color.b
|
||||
end
|
||||
|
||||
function TextWidget:getPadding()
|
||||
return self.padding
|
||||
end
|
||||
|
||||
function TextWidget:getPaddingLeft()
|
||||
return self.paddingLeft or self:getPadding()
|
||||
end
|
||||
|
||||
function TextWidget:getPaddingRight()
|
||||
return self.paddingRight or self:getPadding()
|
||||
end
|
||||
|
||||
function TextWidget:drawCanvas()
|
||||
local w, h
|
||||
local font = self:getFont()
|
||||
|
@ -77,18 +101,31 @@ function TextWidget:drawCanvas()
|
|||
if (complexLabel.position == "center") then
|
||||
w = math.floor(self.width / 2)
|
||||
elseif (complexLabel.position == "left") then
|
||||
w = self:getPadding()
|
||||
w = self:getPaddingLeft()
|
||||
elseif (complexLabel.position == "right") then
|
||||
w = math.floor(self.width - self:getPadding())
|
||||
w = math.floor(self.width - self:getPaddingRight())
|
||||
else
|
||||
error("Position " .. complexLabel.position .. " is unknown for label " .. complexLabel.label)
|
||||
end
|
||||
font:draw(complexLabel.label, w, h, -1, complexLabel.position)
|
||||
end
|
||||
end
|
||||
|
||||
function TextWidget:draw(x, y, w, h)
|
||||
local r, g, b = self:getColor()
|
||||
love.graphics.setColor(r, g, b, 1)
|
||||
if self.canvas.texture ~= nil then
|
||||
love.graphics.draw(self.canvas.texture, x, y)
|
||||
end
|
||||
utils.graphics.resetColor()
|
||||
end
|
||||
|
||||
function TextWidget:drawSelected(x, y, w, h)
|
||||
local r, g, b = self:getSelectedColor()
|
||||
love.graphics.setColor(r, g, b, 1)
|
||||
self:draw(x, y)
|
||||
if self.canvas.texture ~= nil then
|
||||
love.graphics.draw(self.canvas.texture, x, y)
|
||||
end
|
||||
utils.graphics.resetColor()
|
||||
end
|
||||
|
94
birb/modules/gui/mixins/elements.lua
Normal file
94
birb/modules/gui/mixins/elements.lua
Normal file
|
@ -0,0 +1,94 @@
|
|||
local ElementList = Object:extend()
|
||||
|
||||
function ElementList:initElements()
|
||||
self.elements = {}
|
||||
self.focusedElement = nil
|
||||
self.lastFocused = nil
|
||||
self.nbrElement = 0
|
||||
end
|
||||
|
||||
function ElementList:addElement(name, element)
|
||||
self.nbrElement = self.nbrElement + 1
|
||||
self.elements[name] = element
|
||||
return self.nbrElement
|
||||
end
|
||||
|
||||
function ElementList:deleteElement(name)
|
||||
self.elements[name] = nil
|
||||
end
|
||||
|
||||
function ElementList:setFocus(name, widgetId, page)
|
||||
assert(self:elementExists(name), "Element " .. name .. " doesn't exists")
|
||||
self:storeLastFocus()
|
||||
self.focusedElement = name
|
||||
self.elements[name].isVisible = true
|
||||
if (widgetId ~= nil) then
|
||||
self.elements[name]:setSubFocus(widgetId, page)
|
||||
end
|
||||
end
|
||||
|
||||
function ElementList:removeFocus()
|
||||
self:storeLastFocus()
|
||||
self.focusedElement = nil
|
||||
end
|
||||
|
||||
function ElementList:storeLastFocus()
|
||||
if (self.focusedElement ~= nil) then
|
||||
self.lastFocused = self.focusedElement
|
||||
end
|
||||
end
|
||||
|
||||
function ElementList:setLastFocus()
|
||||
if (self:elementExists(self.lastFocused)) then
|
||||
self:setFocus(self.lastFocused)
|
||||
end
|
||||
end
|
||||
|
||||
function ElementList:elementExists(name)
|
||||
return (self:getElement(name) ~= nil)
|
||||
end
|
||||
|
||||
function ElementList:haveFocus()
|
||||
return self:elementIsVisible(self.focusedElement)
|
||||
end
|
||||
|
||||
function ElementList:getFocusedElement()
|
||||
return self:getElement(self.focusedElement)
|
||||
end
|
||||
|
||||
function ElementList:getElement(name)
|
||||
if (not utils.string.isEmpty(name)) then
|
||||
return self.elements[name]
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
||||
function ElementList:getVisibleElement(topLayer)
|
||||
local visibleList = {}
|
||||
for _, element in pairs(self.elements) do
|
||||
if (element ~= nil) then
|
||||
if (element:getVisibility() and ((element.depth) < 0 == topLayer)) then
|
||||
table.insert(visibleList, element)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
table.sort(visibleList, function (a, b)
|
||||
if (a.depth == b.depth) then
|
||||
return (a.creationId < b.creationId)
|
||||
else
|
||||
return (a.depth > b.depth)
|
||||
end
|
||||
end)
|
||||
|
||||
return visibleList
|
||||
end
|
||||
|
||||
function ElementList:elementIsVisible(name)
|
||||
if (self:elementExists(name)) then
|
||||
return self.elements[name]:getVisibility()
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
return ElementList
|
20
birb/modules/gui/mixins/screens.lua
Normal file
20
birb/modules/gui/mixins/screens.lua
Normal file
|
@ -0,0 +1,20 @@
|
|||
local ScreenList = Object:extend()
|
||||
|
||||
function ScreenList:initScreens()
|
||||
self.screens = {}
|
||||
end
|
||||
|
||||
function ScreenList:addScreen(name, screen)
|
||||
self.screens[name] = screen
|
||||
end
|
||||
|
||||
function ScreenList:deleteScreen(name)
|
||||
self.screens[name]:purgeElements()
|
||||
self.screens[name] = nil
|
||||
end
|
||||
|
||||
function ScreenList:getScreen(name)
|
||||
return self.screens[name]
|
||||
end
|
||||
|
||||
return ScreenList
|
160
birb/modules/gui/screen/init.lua
Normal file
160
birb/modules/gui/screen/init.lua
Normal file
|
@ -0,0 +1,160 @@
|
|||
local GuiScreen = Object:extend()
|
||||
local ElementList = require "birb.modules.gui.mixins.elements"
|
||||
GuiScreen:implement(ElementList)
|
||||
|
||||
local TweenManager = require "birb.classes.time"
|
||||
local ScreenSet = require "birb.modules.gui.screen.screenset"
|
||||
|
||||
local elementDataStruct = require "birb.structures.elementData"
|
||||
|
||||
function GuiScreen:new(name)
|
||||
self:initWrapper()
|
||||
self.name = name
|
||||
self.isVisible = false
|
||||
self.transforms = {}
|
||||
self.tweens = TweenManager(self)
|
||||
|
||||
self:reset()
|
||||
self:registerElements()
|
||||
self.gui:addScreen(name, self)
|
||||
|
||||
self.defaultFocus = nil
|
||||
end
|
||||
|
||||
function GuiScreen:initWrapper()
|
||||
local scene = core.scenemanager.nextScene or core.scenemanager.currentScene
|
||||
self.scene = scene
|
||||
self.gui = scene.gui
|
||||
-- Présent pour la compatibilité
|
||||
self.controller = self.gui
|
||||
self.assets = scene.assets
|
||||
end
|
||||
|
||||
function GuiScreen:update(dt)
|
||||
self.tweens:update(dt)
|
||||
end
|
||||
|
||||
function GuiScreen:show(focusElement, widgetId, page)
|
||||
self:showSimple(focusElement, widgetId, page)
|
||||
if (self.set ~= nil) then
|
||||
self.set.owner:show()
|
||||
end
|
||||
end
|
||||
|
||||
function GuiScreen:showSimple(focusElement, widgetId, page)
|
||||
focusElement = focusElement or self.defaultFocus
|
||||
if (not self.isVisible) then
|
||||
self.isVisible = true
|
||||
local delay = 0
|
||||
if (self.set ~= nil) then
|
||||
delay = self.set:setCurrentScreen(self.name)
|
||||
end
|
||||
|
||||
if (self.transforms["show"] ~= nil) then
|
||||
if (delay == 0) then
|
||||
self:showWithSubScreen(focusElement, widgetId, page)
|
||||
else
|
||||
self.tweens:newFunc(delay, "focus", function () self:showWithSubScreen(focusElement, widgetId, page) end)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function GuiScreen:showWithSubScreen(focusElement, widgetId, page)
|
||||
self:playTransform("show")
|
||||
if (focusElement ~= nil) then
|
||||
self.gui:setFocus(focusElement, widgetId, page)
|
||||
end
|
||||
|
||||
if (self.subscreens ~= nil) then
|
||||
self.subscreens:show()
|
||||
end
|
||||
end
|
||||
|
||||
function GuiScreen:setDatas(datas)
|
||||
|
||||
end
|
||||
|
||||
function GuiScreen:hide()
|
||||
local time = 0
|
||||
if (self.isVisible) then
|
||||
if (self.transforms["hide"] ~= nil) then
|
||||
time = self:playTransform("hide")
|
||||
self.tweens:newFunc(time, "hide", function ()
|
||||
self.isVisible = false
|
||||
end)
|
||||
end
|
||||
|
||||
if (self.subscreens ~= nil) then
|
||||
self.subscreens:hideCurrent()
|
||||
end
|
||||
end
|
||||
return time
|
||||
end
|
||||
|
||||
function GuiScreen:addTransform(name, transform)
|
||||
self.transforms[name] = transform
|
||||
end
|
||||
|
||||
function GuiScreen:playTransform(name, delay)
|
||||
return self.gui:transform(self.transforms[name], delay)
|
||||
end
|
||||
|
||||
function GuiScreen:reset()
|
||||
self:initElements()
|
||||
end
|
||||
|
||||
function GuiScreen:registerElements()
|
||||
local elementList = self:createElements()
|
||||
for _, rawElement in ipairs(elementList) do
|
||||
if (rawElement.is ~= nil) then
|
||||
self:addElement(rawElement.name, rawElement)
|
||||
rawElement.screen = self
|
||||
else
|
||||
local elemData = utils.table.parse(rawElement, elementDataStruct, 3)
|
||||
local element = elemData.element
|
||||
self:addElement(element.name, element)
|
||||
if (elemData.focus == true) then
|
||||
element:getFocus()
|
||||
end
|
||||
if (elemData.delay > 0) then
|
||||
element.isVisible = false
|
||||
element:newSwitch(elemData.delay, {"isVisible"})
|
||||
end
|
||||
if (elemData.depth ~= nil) then
|
||||
element.depth = elemData.depth
|
||||
end
|
||||
if (elemData.keypress ~= nil) then
|
||||
element:setKeyPressAction(elemData.keypress)
|
||||
end
|
||||
element.screen = self
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function GuiScreen:createElements()
|
||||
-- Empty function
|
||||
end
|
||||
|
||||
function GuiScreen:setParentSet(set)
|
||||
self.set = set
|
||||
end
|
||||
|
||||
function GuiScreen:addSubscreen(screen)
|
||||
self:initSubscreen()
|
||||
self.subscreens:add(screen)
|
||||
end
|
||||
|
||||
function GuiScreen:showSubscreen(screenname)
|
||||
if (self.subscreens ~= nil) then
|
||||
self.subscreens:show(screenname)
|
||||
end
|
||||
end
|
||||
|
||||
function GuiScreen:initSubscreen()
|
||||
if (self.subscreens == nil) then
|
||||
self.subscreens = ScreenSet(self)
|
||||
end
|
||||
end
|
||||
|
||||
return GuiScreen
|
73
birb/modules/gui/screen/screenset.lua
Normal file
73
birb/modules/gui/screen/screenset.lua
Normal file
|
@ -0,0 +1,73 @@
|
|||
-- screens/screenset :: a set of exclusive screens
|
||||
-- Useful to handle a complexe menu with several screens
|
||||
|
||||
--[[
|
||||
Copyright © 2021 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 ScreenSet = Object:extend()
|
||||
|
||||
function ScreenSet:new(owner)
|
||||
self.set = {}
|
||||
self.defaultScreen = ""
|
||||
self.currentScreen = ""
|
||||
self.owner = owner
|
||||
self.delay = 0
|
||||
end
|
||||
|
||||
function ScreenSet:show(screenName)
|
||||
local screenName = screenName
|
||||
if (screenName == nil) then
|
||||
if self.currentScreen == "" then
|
||||
screenName = self.defaultScreen
|
||||
else
|
||||
return
|
||||
end
|
||||
end
|
||||
if screenName ~= "" then
|
||||
self.set[screenName]:showSimple()
|
||||
end
|
||||
end
|
||||
|
||||
function ScreenSet:setCurrentScreen(screenName)
|
||||
screenName = screenName or self.defaultScreen
|
||||
local time = self:hideCurrent() + self.delay
|
||||
self.currentScreen = screenName
|
||||
return time
|
||||
end
|
||||
|
||||
function ScreenSet:hideCurrent()
|
||||
local time = 0
|
||||
if (self.currentScreen ~= "") then
|
||||
time = self.set[self.currentScreen]:hide()
|
||||
self.currentScreen = ""
|
||||
end
|
||||
return time
|
||||
end
|
||||
|
||||
function ScreenSet:add(screen, setAsDefault)
|
||||
self.set[screen.name] = screen
|
||||
if (setAsDefault == true or self.defaultScreen == "") then
|
||||
self.defaultScreen = screen.name
|
||||
end
|
||||
screen:setParentSet(self)
|
||||
end
|
||||
|
||||
return ScreenSet
|
|
@ -24,24 +24,49 @@
|
|||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
]]
|
||||
|
||||
local ListBox = require "birb.modules.menusystem.menus.listbox"
|
||||
local ListBox = require "birb.modules.gui.menus.listbox"
|
||||
local TextMenu = ListBox:extend()
|
||||
|
||||
TextMenu.baseWidgets = require "birb.modules.menusystem.textmenu.widgets"
|
||||
TextMenu.baseWidgets = require "birb.modules.gui.textmenu.widgets"
|
||||
|
||||
local BASE_PADDING = 8
|
||||
|
||||
function TextMenu:new(name, font, x, y, w, slotNumber, padding)
|
||||
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.name = name
|
||||
local h = self.font:getHeight() * slotNumber
|
||||
|
||||
self.padding = padding or BASE_PADDING
|
||||
self:setSelectedColor(1,1,1)
|
||||
TextMenu.super.new(self, nil, name, x, y, w, h, slotNumber)
|
||||
TextMenu.super.new(self, name, x, y, w, (self.lineHeight * slotNumber), slotNumber)
|
||||
end
|
||||
|
||||
function TextMenu:addItem(text, position, func, type, additionnalItems, color, additionnalDatas)
|
||||
local widget = TextMenu.baseWidgets.Base(self.name, text, position)
|
||||
widget:setFunc(func)
|
||||
widget.type = type or "select"
|
||||
if (additionnalItems ~= nil) then
|
||||
for _, item in ipairs(additionnalItems) do
|
||||
widget:addLabel(item[1], item[2])
|
||||
end
|
||||
end
|
||||
if (color ~= nil) then
|
||||
widget:setColor(color[1], color[2], color[3])
|
||||
end
|
||||
if (additionnalDatas ~= nil) then
|
||||
widget.datas = additionnalDatas
|
||||
end
|
||||
end
|
||||
|
||||
function TextMenu:generateSubmenu(pageName, label, parent, list, func, backWidget)
|
||||
self:addSubmenu(pageName, label, parent, backWidget)
|
||||
for _, data in ipairs(list) do
|
||||
self:addItem(func(data))
|
||||
end
|
||||
end
|
||||
|
||||
function TextMenu:setFont(fontName)
|
||||
local scene = core.scenemanager.currentScene
|
||||
local scene = core.scenemanager.nextScene or core.scenemanager.currentScene
|
||||
self.font = scene.assets:getFont(fontName)
|
||||
end
|
||||
|
||||
|
@ -57,13 +82,22 @@ function TextMenu:setSelectedColor(r, g, b)
|
|||
end
|
||||
|
||||
function TextMenu:getSelectedColor()
|
||||
return self.selectedColor.r, self.selectedColor.g, self.selectedColor.b
|
||||
return self.selectedColor
|
||||
end
|
||||
|
||||
function TextMenu:getPadding()
|
||||
return self.padding
|
||||
end
|
||||
|
||||
function TextMenu:getPaddingLeft()
|
||||
return self.paddingLeft or self:getPadding()
|
||||
end
|
||||
|
||||
function TextMenu:getPaddingRight()
|
||||
return self.paddingRight or self:getPadding()
|
||||
end
|
||||
|
||||
|
||||
function TextMenu:addSubmenu(pageName, label, parent, backWidget)
|
||||
local label = label or pageName
|
||||
local parent = parent or "main"
|
||||
|
@ -72,6 +106,7 @@ function TextMenu:addSubmenu(pageName, label, parent, backWidget)
|
|||
TextMenu.super.addSubmenu(self, pageName, parent)
|
||||
if (backWidget ~= false) then
|
||||
TextMenu.baseWidgets.Back(self.name)
|
||||
self:setCancelWidget("last")
|
||||
end
|
||||
end
|
||||
|
|
@ -21,7 +21,7 @@
|
|||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
]]
|
||||
|
||||
local TextMenuWidget = require "birb.modules.menusystem.textmenu.widgets.basic"
|
||||
local TextMenuWidget = require "birb.modules.gui.textmenu.widgets.basic"
|
||||
|
||||
local BackWidget = TextMenuWidget:extend()
|
||||
|
|
@ -23,7 +23,7 @@
|
|||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
]]
|
||||
|
||||
local TextWidget = require "birb.modules.menusystem.menus.widgets.text"
|
||||
local TextWidget = require "birb.modules.gui.menus.widgets.text"
|
||||
|
||||
local TextMenuWidget = TextWidget:extend()
|
||||
|
||||
|
@ -37,11 +37,24 @@ function TextMenuWidget:getFont()
|
|||
end
|
||||
|
||||
function TextMenuWidget:getSelectedColor()
|
||||
return self.menu:getSelectedColor()
|
||||
local selectedColor = self.menu:getSelectedColor()
|
||||
if (selectedColor ~= nil) then
|
||||
return selectedColor.r, selectedColor.g, selectedColor.b
|
||||
else
|
||||
return self:getColor()
|
||||
end
|
||||
end
|
||||
|
||||
function TextMenuWidget:getPadding()
|
||||
return self.menu:getPadding()
|
||||
end
|
||||
|
||||
function TextWidget:getPaddingLeft()
|
||||
return self.menu:getPaddingLeft() or self:getPadding()
|
||||
end
|
||||
|
||||
function TextWidget:getPaddingRight()
|
||||
return self.menu:getPaddingRight() or self:getPadding()
|
||||
end
|
||||
|
||||
return TextMenuWidget
|
|
@ -24,8 +24,8 @@
|
|||
local Widget = {}
|
||||
|
||||
-- Add the widget as subvariable to the returned table
|
||||
Widget.Base = require "birb.modules.menusystem.textmenu.widgets.basic"
|
||||
Widget.SubMenu= require "birb.modules.menusystem.textmenu.widgets.submenu"
|
||||
Widget.Back = require "birb.modules.menusystem.textmenu.widgets.back"
|
||||
Widget.Base = require "birb.modules.gui.textmenu.widgets.basic"
|
||||
Widget.SubMenu= require "birb.modules.gui.textmenu.widgets.submenu"
|
||||
Widget.Back = require "birb.modules.gui.textmenu.widgets.back"
|
||||
|
||||
return Widget
|
|
@ -22,7 +22,7 @@
|
|||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
]]
|
||||
|
||||
local TextMenuWidget = require "birb.modules.menusystem.textmenu.widgets.basic"
|
||||
local TextMenuWidget = require "birb.modules.gui.textmenu.widgets.basic"
|
||||
|
||||
local SubmenuWidget = TextMenuWidget:extend()
|
||||
|
|
@ -1,33 +0,0 @@
|
|||
-- modules : different modules that are usable as part of birb
|
||||
|
||||
--[[
|
||||
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 modules = {}
|
||||
|
||||
local cwd = (...):gsub('%.init$', '') .. "."
|
||||
|
||||
modules.Assets = require(cwd .. "assets")
|
||||
modules.GameSystem = require(cwd .. "gamesystem")
|
||||
modules.MenuSystem = require(cwd .. "menusystem")
|
||||
modules.Timers = require(cwd .. "timers")
|
||||
|
||||
return modules
|
|
@ -1,285 +0,0 @@
|
|||
-- menusystem :: the controller of the menu system. This object handle the
|
||||
-- different menu objects
|
||||
|
||||
--[[
|
||||
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('%.init$', '') .. "."
|
||||
|
||||
local MenuSystem = Object:extend()
|
||||
|
||||
-- Load the differents menu object to get an easy access
|
||||
MenuSystem.Parent = require(cwd .. "menus.parent")
|
||||
MenuSystem.ListBox = require(cwd .. "menus.listbox")
|
||||
MenuSystem.FlowBox = require(cwd .. "menus.flowbox")
|
||||
MenuSystem.Grid = require(cwd .. "menus.grid")
|
||||
|
||||
-- load widgets object
|
||||
MenuSystem.Widget = require(cwd .. "menus.widgets")
|
||||
|
||||
-- INIT FUNCTIONS
|
||||
-- Initialize and configure the menu controller
|
||||
|
||||
function MenuSystem:new(scene)
|
||||
self.scene = scene
|
||||
self.menus = {}
|
||||
self.focusedMenu = ""
|
||||
self.isActive = true
|
||||
self.lockWorld = false
|
||||
self.lockAssets = false
|
||||
end
|
||||
|
||||
function MenuSystem:reset()
|
||||
self.menus = {}
|
||||
end
|
||||
|
||||
-- ACTIVATION FUNCTIONS
|
||||
-- Activate and deactivate the whole menusystem
|
||||
|
||||
function MenuSystem:activate()
|
||||
self.isActive = true
|
||||
|
||||
if (self.lockWorld) then
|
||||
if (self.scene.world ~= nil) then
|
||||
self.scene.world:setActivity(false)
|
||||
end
|
||||
end
|
||||
|
||||
if (self.lockAssets) then
|
||||
if (self.scene.assets ~= nil) then
|
||||
self.scene.assets:setActivity(false)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function MenuSystem:deactivate()
|
||||
self.isActive = false
|
||||
|
||||
if (self.lockWorld) then
|
||||
if (self.scene.world ~= nil) then
|
||||
self.scene.world:setActivity(true)
|
||||
end
|
||||
end
|
||||
|
||||
if (self.lockAssets) then
|
||||
if (self.scene.assets ~= nil) then
|
||||
self.scene.assets:setActivity(true)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function MenuSystem:getActiveState()
|
||||
return self.isActive
|
||||
end
|
||||
|
||||
function MenuSystem:lockWorldWhenActive(state)
|
||||
self.lockWorld = state
|
||||
end
|
||||
|
||||
function MenuSystem:lockAssetsWhenActive(state)
|
||||
self.lockAssets = state
|
||||
end
|
||||
|
||||
|
||||
-- MENUS FUNCTIONS
|
||||
-- Controle the menus of the menusystem
|
||||
|
||||
function MenuSystem:addMenu(name, menu)
|
||||
self.menus[name] = menu
|
||||
end
|
||||
|
||||
function MenuSystem:getMenu(name)
|
||||
return self.menus[name]
|
||||
end
|
||||
|
||||
function MenuSystem:menuExist(name)
|
||||
return (self.menus[name] ~= nil)
|
||||
end
|
||||
|
||||
function MenuSystem:switchMenu(menuName)
|
||||
for name, guiElement in pairs(self.menus) do
|
||||
if (name == menuName) then
|
||||
guiElement:getFocus()
|
||||
guiElement:setVisibility(true)
|
||||
guiElement:setActivity(true)
|
||||
else
|
||||
guiElement:setVisibility(false)
|
||||
guiElement:setActivity(false)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function MenuSystem:lockMenu(menu, lock)
|
||||
local lock = lock or true
|
||||
if self:menuExist(menu) then
|
||||
self.menus[menu]:lock(lock)
|
||||
end
|
||||
end
|
||||
|
||||
function MenuSystem:lockMenuVisibility(menu, lock)
|
||||
local lock = lock or true
|
||||
if self:menuExist(menu) then
|
||||
self.menus[menu]:lockVisibility(lock)
|
||||
end
|
||||
end
|
||||
|
||||
function MenuSystem:setMenuActivity(menu, activity)
|
||||
local activity = activity or true
|
||||
if self:menuExist(menu) then
|
||||
self.menus[menu]:setActivity(activity)
|
||||
if activity == true then
|
||||
-- if we make the menu active, he have to be visible too
|
||||
self.menus[menu]:setVisibility(true)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function MenuSystem:setMenuVisibility(menu, visibility)
|
||||
local visibility = visibility or true
|
||||
if self:menuExist(menu) then
|
||||
self.menus[menu]:setVisibility(visibility)
|
||||
end
|
||||
end
|
||||
|
||||
function MenuSystem:setAllMenuVisibility(visibility)
|
||||
for _, guiElement in pairs(self.menus) do
|
||||
guiElement:setVisibility(visibility)
|
||||
end
|
||||
end
|
||||
|
||||
function MenuSystem:setAllMenuActivity(activity)
|
||||
for _, guiElement in pairs(self.menus) do
|
||||
guiElement.isActive = activity
|
||||
end
|
||||
end
|
||||
|
||||
function MenuSystem:removeDestroyedMenus()
|
||||
-- On retire les entitées marquées comme supprimées
|
||||
for name, guiElement in pairs(self.menus) do
|
||||
if (guiElement.isDestroyed == true) then
|
||||
self.menus[name] = nil
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- SOUND FUNCTIONS
|
||||
-- Add sounds to every menus
|
||||
-- TODO: rework to be used directly by widgets later
|
||||
|
||||
function MenuSystem:setSoundFromSceneAssets(soundname)
|
||||
for _, guiElement in pairs(self.menus) do
|
||||
guiElement:setSoundFromSceneAssets(soundname)
|
||||
end
|
||||
end
|
||||
|
||||
function MenuSystem:setSound(soundasset)
|
||||
for _, guiElement in pairs(self.menus) do
|
||||
guiElement:setSound(soundasset)
|
||||
end
|
||||
end
|
||||
|
||||
-- UPDATE FUNCTIONS
|
||||
-- Update the menus of the menusystem
|
||||
|
||||
function MenuSystem:update(dt)
|
||||
if (self.isActive) then
|
||||
self:removeDestroyedMenus()
|
||||
for _, guiElement in pairs(self.menus) do
|
||||
guiElement:updateElement(dt)
|
||||
end
|
||||
|
||||
if self.menus[self.focusedMenu] ~= nil then
|
||||
-- Only check buttons if the current focused menu is actually active
|
||||
if self.menus[self.focusedMenu].isActive then
|
||||
for keyname, keydata in pairs(self.keys) do
|
||||
if self.keys[keyname].isPressed then
|
||||
self.menus[self.focusedMenu]:keyreleased(keyname)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- MOUSE FUNCTIONS
|
||||
-- Send mouse inputs to the menu
|
||||
|
||||
function MenuSystem:mousemoved(x, y, dx, dy)
|
||||
if (self.isActive) then
|
||||
|
||||
for _, guiElement in pairs(self.menus) do
|
||||
if guiElement.isActive then
|
||||
if guiElement:areCoordInside(x, y) then
|
||||
local xx, yy = guiElement:getRelativeCoordinate(x, y)
|
||||
guiElement:mousemoved(xx, yy)
|
||||
break;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
function MenuSystem:mousepressed( x, y, button, istouch )
|
||||
if (self.isActive) then
|
||||
for _, guiElement in pairs(self.menus) do
|
||||
if guiElement.isActive then
|
||||
if guiElement:areCoordInside(x, y) then
|
||||
local xx, yy = guiElement:getRelativeCoordinate(x, y)
|
||||
guiElement:mousepressed(xx, yy, button, istouch )
|
||||
break;
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- DRAW FUNCTIONS
|
||||
-- All functions to draw the menus of the menusystem
|
||||
|
||||
function MenuSystem:getDrawList()
|
||||
local drawList = {}
|
||||
for name, guiElement in pairs(self.menus) do
|
||||
local drawObject = {}
|
||||
drawObject.name = name
|
||||
drawObject.depth = guiElement.depth
|
||||
table.insert(drawList, drawObject)
|
||||
end
|
||||
table.sort(drawList, function(a,b) return a.depth > b.depth end)
|
||||
|
||||
return drawList
|
||||
end
|
||||
|
||||
function MenuSystem:draw(dt)
|
||||
if (self.isActive) then
|
||||
-- Draw all the menus
|
||||
self.drawList = self:getDrawList()
|
||||
|
||||
for _, drawObject in ipairs(self.drawList) do
|
||||
local guiElement = self.menus[drawObject.name]
|
||||
if (guiElement.isVisible) then
|
||||
guiElement:drawElement(dt)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return MenuSystem
|
|
@ -1,119 +0,0 @@
|
|||
local Rect = require "birb.objects.2D.rect"
|
||||
|
||||
local GuiElement = Rect:extend()
|
||||
|
||||
function GuiElement:new(name, x, y, w, h)
|
||||
GuiElement.super.new(self, x, y, w, h)
|
||||
self.name = name
|
||||
|
||||
self.isDestroyed = false
|
||||
self.isVisible = true
|
||||
self.isActive = true
|
||||
self.isLocked = false
|
||||
self.isAlwaysVisible = false
|
||||
|
||||
self.depth = 0
|
||||
|
||||
self:register()
|
||||
end
|
||||
|
||||
function GuiElement:getGui()
|
||||
local scene = core.scenemanager.currentScene
|
||||
return scene.menusystem
|
||||
end
|
||||
|
||||
function GuiElement:register()
|
||||
local gui = self:getGui()
|
||||
gui:addMenu(self.name, self)
|
||||
end
|
||||
|
||||
function GuiElement:destroy()
|
||||
self.destroyed = true
|
||||
end
|
||||
|
||||
-- VISIBILITY/ACTIVITY
|
||||
-- Handle drawing and how we interact with
|
||||
|
||||
function GuiElement:setDepth(depth)
|
||||
self.depth = depth or 0
|
||||
end
|
||||
|
||||
function GuiElement:setVisibility(visibility)
|
||||
if self.isLocked == false and self.isAlwaysVisible == false then
|
||||
self.isVisible = visibility
|
||||
else
|
||||
-- if the element is locked (thus is always active), it should also
|
||||
-- be always visible.
|
||||
self.isVisible = true
|
||||
end
|
||||
end
|
||||
|
||||
function GuiElement:setActivity(activity)
|
||||
if self.isLocked == false then
|
||||
self.isActive = activity
|
||||
else
|
||||
self.isActive = true
|
||||
end
|
||||
end
|
||||
|
||||
function GuiElement:lock(lock)
|
||||
self.isLocked = lock
|
||||
end
|
||||
|
||||
function GuiElement:lockVisibility(lock)
|
||||
self.isAlwaysVisible = lock
|
||||
end
|
||||
|
||||
function GuiElement:getFocus()
|
||||
local gui = self:getGui()
|
||||
gui.focusedMenu = self.name
|
||||
end
|
||||
|
||||
function GuiElement:haveFocus()
|
||||
local gui = self:getGui()
|
||||
return (gui.focusedMenu == self.name)
|
||||
end
|
||||
|
||||
-- UPDATE FUNCTIONS
|
||||
-- Update the menu every game update
|
||||
|
||||
-- External update function
|
||||
function GuiElement:updateElement(dt)
|
||||
self:update(dt)
|
||||
end
|
||||
|
||||
-- Internal update function
|
||||
function GuiElement:update(dt)
|
||||
-- Cette fonction ne contient rien par défaut
|
||||
end
|
||||
|
||||
-- DRAW FUNCTIONS
|
||||
-- Draw the menu and its content
|
||||
|
||||
function GuiElement:drawElement()
|
||||
self:draw()
|
||||
end
|
||||
|
||||
function GuiElement:draw()
|
||||
-- nothing here
|
||||
end
|
||||
|
||||
-- KEYBOARD FUNCTIONS
|
||||
-- Handle key press
|
||||
|
||||
function GuiElement:keyreleased(key)
|
||||
-- Cette fonction ne contient rien par défaut
|
||||
end
|
||||
|
||||
-- MOUSE FUNCTIONS
|
||||
-- Handle pointers (clic/touch)
|
||||
|
||||
function GuiElement:mousemoved(x, y)
|
||||
-- Cette fonction ne contient rien par défaut
|
||||
end
|
||||
|
||||
function GuiElement:mousepressed(x, y, button, istouch)
|
||||
-- Cette fonction ne contient rien par défaut
|
||||
end
|
||||
|
||||
return GuiElement
|
|
@ -27,35 +27,29 @@ local cwd = (...):gsub('%.scenes$', '') .. "."
|
|||
local Scene = Object:extend()
|
||||
|
||||
local Assets = require(cwd .. "assets")
|
||||
local MenuSystem = require(cwd .. "menusystem")
|
||||
local Gui = require (cwd .. "gui")
|
||||
|
||||
-- INIT FUNCTIONS
|
||||
-- Initialize and configure the scene
|
||||
|
||||
function Scene:new(args)
|
||||
function Scene:new()
|
||||
self.mouse = {}
|
||||
self.mouse.x, self.mouse.y = core.screen:getMousePosition()
|
||||
|
||||
self.assets = Assets()
|
||||
self.menusystem = MenuSystem(self)
|
||||
self.sources = core.input:getSources()
|
||||
self.gui = Gui(self)
|
||||
|
||||
self.inputLocked = true
|
||||
self.inputLockedTimer = 2
|
||||
self:flushKeys()
|
||||
self.isActive = false
|
||||
|
||||
self.args = args
|
||||
self.dialog = nil
|
||||
|
||||
self:initWorld()
|
||||
|
||||
self:register()
|
||||
end
|
||||
|
||||
function Scene:start()
|
||||
-- Empty function
|
||||
end
|
||||
|
||||
function Scene:register()
|
||||
core.scenemanager:setScene(self)
|
||||
end
|
||||
|
@ -64,13 +58,18 @@ function Scene:clear()
|
|||
-- TODO: send automatic cleanups to the different elements of the scene
|
||||
end
|
||||
|
||||
function Scene:restored()
|
||||
|
||||
end
|
||||
|
||||
-- UPDATE FUNCTIONS
|
||||
-- Handle stuff that happens every steps
|
||||
|
||||
function Scene:updateScene(dt)
|
||||
self:updateStart(dt)
|
||||
self:setKeys()
|
||||
self.menusystem:update(dt)
|
||||
self.assets:update(dt)
|
||||
self:updateGUI(dt)
|
||||
self:updateWorld(dt)
|
||||
self:update(dt)
|
||||
self:updateEnd(dt)
|
||||
|
@ -89,11 +88,20 @@ function Scene:updateEnd(dt)
|
|||
end
|
||||
|
||||
function Scene:updateWorld(dt)
|
||||
if (self.world ~= nil) and (self.world.isActive) then
|
||||
if ((self.world ~= nil) and (self.world.isActive) and (self.dialog == nil)) then
|
||||
self.world:update(dt)
|
||||
end
|
||||
end
|
||||
|
||||
function Scene:updateGUI(dt)
|
||||
if (self.gui ~= nil) then
|
||||
self.gui:update(dt)
|
||||
if (core.screen:isActive()) then
|
||||
self.gui:keycheck(self:getKeys(1))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- MOUSE FUNCTIONS
|
||||
-- Make the scene support the pointer
|
||||
|
||||
|
@ -130,12 +138,19 @@ end
|
|||
-- DRAW FUNCTIONS
|
||||
-- Draw the scene and its content
|
||||
|
||||
function Scene:redraw()
|
||||
self.gui:redraw()
|
||||
end
|
||||
|
||||
function Scene:drawScene()
|
||||
self:drawStart()
|
||||
self:drawWorld()
|
||||
self:draw()
|
||||
self.menusystem:draw()
|
||||
self.gui:drawBottom()
|
||||
self:drawEnd()
|
||||
core.screen:drawTransition()
|
||||
self.gui:drawTop()
|
||||
self:drawOverTransition()
|
||||
end
|
||||
|
||||
function Scene:drawStart()
|
||||
|
@ -150,6 +165,10 @@ function Scene:drawEnd()
|
|||
|
||||
end
|
||||
|
||||
function Scene:drawOverTransition()
|
||||
|
||||
end
|
||||
|
||||
function Scene:drawWorld(dt)
|
||||
if (self.world ~= nil) then
|
||||
self.world:draw()
|
||||
|
@ -160,36 +179,35 @@ end
|
|||
-- Handle inputs from keyboard/controllers
|
||||
|
||||
function Scene:setKeys()
|
||||
if (self.inputLocked) or (not self.isActive) then
|
||||
if (self.inputLocked) then
|
||||
self.inputLockedTimer = self.inputLockedTimer - 1
|
||||
if (self.inputLockedTimer <= 0 ) then
|
||||
self.inputLocked = false
|
||||
end
|
||||
self.menusystem.keys = self:getKeys(1)
|
||||
else
|
||||
self.sources = core.input.sources
|
||||
self.menusystem.keys = self:getKeys(1)
|
||||
end
|
||||
end
|
||||
|
||||
function Scene:getKeys(sourceid)
|
||||
if sourceid == nil then
|
||||
core.debug:logWarn("scene", "no sourceid detected, will default to 1")
|
||||
core.debug:warning("scene", "no sourceid detected, will default to 1")
|
||||
end
|
||||
|
||||
local sourceid = sourceid or 1
|
||||
if (self.inputLocked) or (not self.isActive) then
|
||||
core.debug:logDebug("scene", "inputs are currently locked")
|
||||
|
||||
if (self.inputLocked) then
|
||||
core.debug:print("scene", "inputs are currently locked")
|
||||
return core.input.fakekeys
|
||||
else
|
||||
return self.sources[sourceid].keys
|
||||
end
|
||||
end
|
||||
|
||||
function Scene:flushKeys(timer)
|
||||
function Scene:flushKeys()
|
||||
core.input:flushKeys()
|
||||
self.sources = core.input.sources
|
||||
self.inputLockedTimer = timer or 2
|
||||
self.sources = core.input:getSources()
|
||||
self.inputLockedTimer = 2
|
||||
self.inputLocked = true
|
||||
end
|
||||
|
||||
|
|
33
birb/modules/transitions/canvas.lua
Normal file
33
birb/modules/transitions/canvas.lua
Normal file
|
@ -0,0 +1,33 @@
|
|||
local TransitionParent = require "birb.modules.transitions.parent"
|
||||
local CanvasTransition = TransitionParent:extend()
|
||||
|
||||
function CanvasTransition:new(func, ox, oy, fadeOut, easeIn, easeOut, duration, wait)
|
||||
CanvasTransition.super.new(self, func, ox, oy, fadeOut, easeIn, easeOut, duration, wait)
|
||||
self:generateCanvas(0)
|
||||
end
|
||||
|
||||
function CanvasTransition:update(dt)
|
||||
CanvasTransition.super.update(self, dt)
|
||||
self:generateCanvas(dt)
|
||||
end
|
||||
|
||||
function CanvasTransition:generateCanvas(dt)
|
||||
self.canvas = love.graphics.newCanvas(424, 240)
|
||||
love.graphics.setCanvas(self.canvas)
|
||||
self:drawCanvas(dt)
|
||||
love.graphics.setCanvas()
|
||||
end
|
||||
|
||||
function CanvasTransition:drawCanvas(dt)
|
||||
|
||||
end
|
||||
|
||||
function CanvasTransition:draw()
|
||||
if (self.canvas ~= nil) then
|
||||
love.graphics.setBlendMode("multiply", "premultiplied")
|
||||
love.graphics.draw(self.canvas, 0, 0)
|
||||
love.graphics.setBlendMode("alpha")
|
||||
end
|
||||
end
|
||||
|
||||
return CanvasTransition
|
16
birb/modules/transitions/circle.lua
Normal file
16
birb/modules/transitions/circle.lua
Normal file
|
@ -0,0 +1,16 @@
|
|||
local TransitionParent = require "birb.modules.transitions.canvas"
|
||||
local DefaultTransition = TransitionParent:extend()
|
||||
|
||||
function DefaultTransition:new(func, ox, oy, fadeOut)
|
||||
DefaultTransition.super.new(self, func, ox, oy, fadeOut, "inQuad", "outQuad", 0.8, 0.1)
|
||||
end
|
||||
|
||||
function DefaultTransition:drawCanvas()
|
||||
love.graphics.setColor(0,0,0,1)
|
||||
love.graphics.rectangle("fill", 0, 0, 424, 240)
|
||||
utils.graphics.resetColor()
|
||||
local value = 1 - self.value
|
||||
love.graphics.circle("fill",self.ox, self.oy, (424/2) * 1.5 * value)
|
||||
end
|
||||
|
||||
return DefaultTransition
|
22
birb/modules/transitions/decal.lua
Normal file
22
birb/modules/transitions/decal.lua
Normal file
|
@ -0,0 +1,22 @@
|
|||
local TransitionParent = require "birb.modules.transitions.canvas"
|
||||
local DecalTransition = TransitionParent:extend()
|
||||
|
||||
function DecalTransition:new(func, ox, oy, fadeOut, decal)
|
||||
self.decal = decal
|
||||
DecalTransition.super.new(self, func, ox, oy, fadeOut, "inQuad", "outQuad", 0.8, 0.1)
|
||||
end
|
||||
|
||||
function DecalTransition:loadResources()
|
||||
self.decalDrawable = love.graphics.newImage("assets/transitions/" .. self.decal .. ".png")
|
||||
end
|
||||
|
||||
function DecalTransition:drawCanvas()
|
||||
love.graphics.setColor(0,0,0,1)
|
||||
love.graphics.rectangle("fill", 0, 0, 424, 240)
|
||||
utils.graphics.resetColor()
|
||||
local w, h = self.decalDrawable:getDimensions()
|
||||
local value = (1 - self.value) * (240 / h) * 4
|
||||
love.graphics.draw(self.decalDrawable,self.ox,self.oy,0,value, value, w / 2, h / 2)
|
||||
end
|
||||
|
||||
return DecalTransition
|
14
birb/modules/transitions/default.lua
Normal file
14
birb/modules/transitions/default.lua
Normal file
|
@ -0,0 +1,14 @@
|
|||
local TransitionParent = require "birb.modules.transitions.parent"
|
||||
local DefaultTransition = TransitionParent:extend()
|
||||
|
||||
function DefaultTransition:new(func, ox, oy, fadeOut)
|
||||
DefaultTransition.super.new(self, func, ox, oy, fadeOut, "inQuad", "outQuad", 0.35, 0.1)
|
||||
end
|
||||
|
||||
function DefaultTransition:draw()
|
||||
love.graphics.setColor(0,0,0,self.value)
|
||||
love.graphics.rectangle("fill", 0, 0, 424, 240)
|
||||
utils.graphics.resetColor()
|
||||
end
|
||||
|
||||
return DefaultTransition
|
4
birb/modules/transitions/init.lua
Normal file
4
birb/modules/transitions/init.lua
Normal file
|
@ -0,0 +1,4 @@
|
|||
return {
|
||||
default = require "birb.modules.transitions.default",
|
||||
circle = require "birb.modules.transitions.circle"
|
||||
}
|
42
birb/modules/transitions/parent.lua
Normal file
42
birb/modules/transitions/parent.lua
Normal file
|
@ -0,0 +1,42 @@
|
|||
local TransitionParent = Object:extend()
|
||||
local TweenManager = require "birb.classes.time"
|
||||
|
||||
function TransitionParent:new(func, ox, oy, fadeOut, easeIn, easeOut, duration, wait)
|
||||
self.tween = TweenManager(self)
|
||||
self:loadResources()
|
||||
self.func = func
|
||||
self.ox = ox or 0
|
||||
self.oy = oy or 0
|
||||
self.fadeOut = fadeOut
|
||||
if (self.fadeOut) then
|
||||
self.value = 1
|
||||
self.tween:newTween(wait, duration, {value = 0}, easeOut)
|
||||
else
|
||||
self.value = 0
|
||||
self.tween:newTween(0, duration, {value = 1}, easeIn)
|
||||
end
|
||||
self.tween:newTimer(duration + wait, "isOver")
|
||||
end
|
||||
|
||||
function TransitionParent:loadResources()
|
||||
--vide par defaut
|
||||
end
|
||||
|
||||
function TransitionParent:update(dt)
|
||||
self.tween:update(dt * 1.5)
|
||||
end
|
||||
|
||||
function TransitionParent:timerResponse(timer)
|
||||
if (timer == "isOver") then
|
||||
if (self.func ~= nil) then
|
||||
self.func()
|
||||
end
|
||||
core.screen:transitionOver(self.fadeOut)
|
||||
end
|
||||
end
|
||||
|
||||
function TransitionParent:draw()
|
||||
|
||||
end
|
||||
|
||||
return TransitionParent
|
|
@ -21,10 +21,9 @@
|
|||
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 Rect = require "birb.classes.2D.rect"
|
||||
|
||||
local Rect = require "birb.objects.2D.rect"
|
||||
|
||||
local BaseActor = require("birb.modules.world.actors.mixins.base")
|
||||
local BaseActor = require "birb.modules.world.actors.mixins.base"
|
||||
local SpritedActor = require("birb.modules.world.actors.mixins.sprites")
|
||||
local TimedActor = require("birb.modules.world.actors.mixins.timers")
|
||||
local InputActor = require("birb.modules.world.actors.mixins.inputs")
|
||||
|
@ -37,13 +36,14 @@ Actor2D:implement(TimedActor)
|
|||
Actor2D:implement(InputActor)
|
||||
Actor2D:implement(PhysicalActor)
|
||||
|
||||
local Hitbox = require("birb.modules.world.actors.utils.hitbox2D")
|
||||
local Hitbox = require "birb.modules.world.actors.utils.hitbox2D"
|
||||
|
||||
-- INIT FUNCTIONS
|
||||
-- Initialise the actor and its base functions
|
||||
|
||||
function Actor2D:new(world, type, x, y, w, h, isSolid)
|
||||
Actor2D.super.new(self, x, y, w, h)
|
||||
|
||||
self:init(world, type)
|
||||
self:initPhysics(Hitbox, isSolid)
|
||||
self:initTimers()
|
||||
|
@ -51,10 +51,6 @@ function Actor2D:new(world, type, x, y, w, h, isSolid)
|
|||
self:initKeys()
|
||||
end
|
||||
|
||||
function Actor2D:packForHitbox()
|
||||
return {0, 0, self.w, self.h}
|
||||
end
|
||||
|
||||
function Actor2D:destroy()
|
||||
self.world:removeActor(self)
|
||||
self.mainHitbox:destroy()
|
||||
|
@ -134,6 +130,13 @@ function Actor2D:getViewCenter()
|
|||
return x, y
|
||||
end
|
||||
|
||||
-- HITBOXES FUNCTIONS
|
||||
-- Functions related to actor hitboxes
|
||||
|
||||
function Actor2D:packForHitbox()
|
||||
return {0, 0, self.w, self.h}
|
||||
end
|
||||
|
||||
-- DRAW FUNCTIONS
|
||||
-- Draw the actors.
|
||||
|
||||
|
|
|
@ -22,7 +22,9 @@
|
|||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
]]
|
||||
|
||||
local BasicBox = require "birb.objects.3D.box"
|
||||
local Hitbox = require("birb.modules.world.actors.utils.hitbox3D")
|
||||
local Boxes = require("birb.modules.world.actors.utils.boxes")
|
||||
local BasicBox = require "birb.classes.3D.box"
|
||||
|
||||
local BaseActor = require("birb.modules.world.actors.mixins.base")
|
||||
local SpritedActor = require("birb.modules.world.actors.mixins.sprites")
|
||||
|
@ -39,9 +41,6 @@ Actor3D:implement(InputActor)
|
|||
Actor3D:implement(PhysicalActor)
|
||||
Actor3D:implement(Shape3DActor)
|
||||
|
||||
local Hitbox = require("birb.modules.world.actors.utils.hitbox3D")
|
||||
local Boxes = require("birb.modules.world.actors.utils.boxes")
|
||||
|
||||
-- INIT FUNCTIONS
|
||||
-- Initialise the actor and its base functions
|
||||
|
||||
|
@ -51,6 +50,7 @@ function Actor3D:new(world, type, x, y, z, w, h, d, isSolid)
|
|||
self:initPhysics(Hitbox, isSolid)
|
||||
self:initTimers()
|
||||
self:initSprite()
|
||||
self:initKeys()
|
||||
self:initShape(Boxes, true)
|
||||
end
|
||||
|
||||
|
@ -61,11 +61,6 @@ function Actor3D:destroy()
|
|||
self.isDestroyed = true
|
||||
end
|
||||
|
||||
function Actor3D:packForHitbox()
|
||||
return {0, 0, 0, self.w, self.h, self.d}
|
||||
end
|
||||
|
||||
|
||||
-- PHYSICS FUNCTIONS
|
||||
-- Handle movement and collisions.
|
||||
|
||||
|
@ -152,6 +147,13 @@ function Actor3D:getViewCenter()
|
|||
return x, y - (self.d/2)
|
||||
end
|
||||
|
||||
-- HITBOXES FUNCTIONS
|
||||
-- Functions related to actor hitboxes
|
||||
|
||||
function Actor3D:packForHitbox()
|
||||
return {0, 0, 0, self.w, self.h, self.d}
|
||||
end
|
||||
|
||||
-- DRAW FUNCTIONS
|
||||
-- Draw the actors.
|
||||
|
||||
|
@ -161,10 +163,6 @@ function Actor3D:drawShadow(x, y)
|
|||
utils.graphics.resetColor()
|
||||
end
|
||||
|
||||
function Actor3D:getShape()
|
||||
return (self.x), (self.y - self.z - self.d), self.w, (self.h + self.d)
|
||||
end
|
||||
|
||||
function Actor3D:draw()
|
||||
self:drawStart()
|
||||
if (self.box ~= nil) then
|
||||
|
|
|
@ -26,15 +26,14 @@ local Actor2D = require(cwd .. "actor2D")
|
|||
local GFX = Actor2D:extend()
|
||||
|
||||
function GFX:new(world, x, y, spritename)
|
||||
local baseSprite = world.scene.assets:getWithType(spritename, "sprite")
|
||||
local width, height = baseSprite:getDimensions()
|
||||
local width, height = world.scene.assets.sprites[spritename]:getDimensions()
|
||||
|
||||
GFX.super.new(self, world, "gfx", x - (width/2), y - (height/2), width, height)
|
||||
self:setSprite(spritename, true)
|
||||
end
|
||||
|
||||
function GFX:animationEnded(animation)
|
||||
core.debug:logDebug("gfx2D", 'Current animation "' .. animation .. '" have ended, destroying gfx')
|
||||
core.debug:print("gfx2D", 'Current animation "' .. animation .. '" have ended, destroying gfx')
|
||||
self:destroy()
|
||||
end
|
||||
|
||||
|
|
|
@ -26,15 +26,14 @@ local Actor3D = require(cwd .. "actor3D")
|
|||
local GFX = Actor3D:extend()
|
||||
|
||||
function GFX:new(world, x, y, z, spritename)
|
||||
local baseSprite = world.scene.assets:getWithType(spritename, "sprite")
|
||||
local width, height = baseSprite:getDimensions()
|
||||
local width, height = world.scene.assets.sprites[spritename]:getDimensions()
|
||||
|
||||
GFX.super.new(self, world, "gfx", x - (width/2), y - (width/2), z - (height/2), width, width, height)
|
||||
self:setSprite(spritename, true)
|
||||
end
|
||||
|
||||
function GFX:animationEnded(animation)
|
||||
core.debug:logDebug("gfx3D", 'Current animation "' .. animation .. '" have ended, destroying gfx')
|
||||
core.debug:print("gfx3D", 'Current animation "' .. animation .. '" have ended, destroying gfx')
|
||||
self:destroy()
|
||||
end
|
||||
|
||||
|
|
|
@ -31,13 +31,27 @@ function BaseActor:init(world, type)
|
|||
self.type = type or ""
|
||||
self.depth = 0
|
||||
|
||||
self.updateFunctions = {}
|
||||
|
||||
self:setManagers(world)
|
||||
self:initKeys()
|
||||
|
||||
self:setDebugColor(1, 1, 1)
|
||||
self:register()
|
||||
self.useTileCollision = true
|
||||
end
|
||||
|
||||
self.updateFunctions = {}
|
||||
function BaseActor:setProperties(properties)
|
||||
-- Do something here
|
||||
end
|
||||
|
||||
function BaseActor:addUpdateFunction(func)
|
||||
table.insert(self.updateFunctions, func)
|
||||
end
|
||||
|
||||
function BaseActor:applyUpdateFunctions(dt)
|
||||
for key, func in ipairs(self.updateFunctions) do
|
||||
func(self, dt)
|
||||
end
|
||||
end
|
||||
|
||||
function BaseActor:setManagers(world)
|
||||
|
@ -77,16 +91,6 @@ function BaseActor:update(dt)
|
|||
self:updateEnd(dt)
|
||||
end
|
||||
|
||||
function BaseActor:addUpdateFunction(func)
|
||||
table.insert(self.updateFunctions, func)
|
||||
end
|
||||
|
||||
function BaseActor:applyUpdateFunctions(dt)
|
||||
for key, func in ipairs(self.updateFunctions) do
|
||||
func(self, dt)
|
||||
end
|
||||
end
|
||||
|
||||
function BaseActor:updateEnd(dt)
|
||||
|
||||
end
|
||||
|
@ -107,8 +111,4 @@ function BaseActor:drawEnd()
|
|||
|
||||
end
|
||||
|
||||
function BaseActor:drawHUD(id, height, width)
|
||||
|
||||
end
|
||||
|
||||
return BaseActor
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
-- SpritedActor.lua :: Get input from the world object.
|
||||
-- InputActor.lua :: Get input from the world object.
|
||||
|
||||
--[[
|
||||
Copyright © 2019 Kazhnuz
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
PhysicalActor = Object:extend()
|
||||
local hitboxStructure = require "birb.structures.hitbox"
|
||||
|
||||
-- PHYSICS FUNCTIONS
|
||||
-- Raw implementation of everything common in physics
|
||||
|
@ -143,7 +144,8 @@ function PhysicalActor:initHitboxes(hitboxObj)
|
|||
end
|
||||
|
||||
function PhysicalActor:initMainHitbox()
|
||||
-- Empty function : don't load ANY real hitbox function into PhysicalActor
|
||||
self.mainHitbox = self.Hitbox(self, self.type, self:packForHitbox(), 0, 0, self.isSolid)
|
||||
self.mainHitbox:advertiseAsMainHitbox()
|
||||
end
|
||||
|
||||
function PhysicalActor:setHitboxFile(file)
|
||||
|
@ -175,28 +177,22 @@ end
|
|||
|
||||
function PhysicalActor:addHitboxFromFrameData(framedata, animationID, frameID, hitboxID)
|
||||
local sx, sy = self.sprite:getScalling()
|
||||
local type = framedata[1]
|
||||
local box = framedata[2]
|
||||
local isSolid = framedata[3] or false
|
||||
local hitbox = utils.table.parse(framedata, hitboxStructure, 1)
|
||||
local anim = animationID or "null"
|
||||
local frame = frameID or 0
|
||||
local id = hitboxID or 0
|
||||
|
||||
if (type == "main") then
|
||||
self.mainHitbox:setFromData(box, sx, sy)
|
||||
if (hitbox.type == "main") then
|
||||
self.mainHitbox:setFromData(hitbox.box, sx, sy)
|
||||
else
|
||||
local hitboxName = anim .. frame .. type .. id
|
||||
self:addHitbox(hitboxName, type, box, sx, sy, isSolid)
|
||||
local hitboxName = anim .. frame .. hitbox.type .. id
|
||||
self:addHitbox(hitboxName, hitbox.type, hitbox.box, sx, sy, hitbox.isSolid)
|
||||
return hitboxName
|
||||
end
|
||||
end
|
||||
|
||||
function PhysicalActor:initMainHitbox()
|
||||
self.mainHitbox = self.Hitbox(self, self.type, self:packForHitbox(), 0, 0, self.isSolid)
|
||||
self.mainHitbox:advertiseAsMainHitbox()
|
||||
end
|
||||
|
||||
function PhysicalActor:addHitbox(name, type, data, sx, sy, isSolid)
|
||||
isSolid = (isSolid == true)
|
||||
if (self.hitboxes[name] ~= nil) then
|
||||
core.debug:logWarn("PhysicalActor", "the hitbox " .. name .. " already exists")
|
||||
else
|
||||
|
@ -222,7 +218,7 @@ function PhysicalActor:updateHitboxes()
|
|||
end
|
||||
end
|
||||
|
||||
function PhysicalActor:checkHitboxesCollisions(filter)
|
||||
function PhysicalActor:applyHitboxesCollisions(filter)
|
||||
for k, v in pairs(self.hitboxes) do
|
||||
self:applyHitboxCollisions(k, filter)
|
||||
end
|
||||
|
|
|
@ -37,7 +37,7 @@ end
|
|||
|
||||
function SpritedActor:changeAnimation(animation, restart)
|
||||
if (self.sprite ~= nil) then
|
||||
core.debug:logWarn("actor", "the function SpritedActor:changeAnimation is deprecated, prefer SpritedActor.sprite:changeAnimation()")
|
||||
core.debug:warning("actor", "the function SpritedActor:changeAnimation is deprecated, prefer SpritedActor.sprite:changeAnimation()")
|
||||
self.sprite:changeAnimation(animation, restart)
|
||||
end
|
||||
end
|
||||
|
@ -48,7 +48,7 @@ end
|
|||
|
||||
function SpritedActor:setCustomSpeed(customSpeed)
|
||||
if (self.sprite ~= nil) then
|
||||
core.debug:logWarn("actor", "the function SpritedActor:setCustomSpeed is deprecated, prefer SpritedActor.sprite:setCustomSpeed()")
|
||||
core.debug:warning("actor", "the function SpritedActor:setCustomSpeed is deprecated, prefer SpritedActor.sprite:setCustomSpeed()")
|
||||
self.sprite:setCustomSpeed(customSpeed)
|
||||
end
|
||||
end
|
||||
|
@ -61,33 +61,33 @@ end
|
|||
|
||||
function SpritedActor:getCurrentAnimation()
|
||||
if (self.sprite ~= nil) then
|
||||
core.debug:logWarn("actor", "the function SpritedActor:getCurrentAnimation is deprecated, prefer SpritedActor.sprite:getCurrentAnimation()")
|
||||
core.debug:warning("actor", "the function SpritedActor:getCurrentAnimation is deprecated, prefer SpritedActor.sprite:getCurrentAnimation()")
|
||||
return self.sprite:getCurrentAnimation()
|
||||
end
|
||||
end
|
||||
|
||||
function SpritedActor:getSpriteScalling()
|
||||
core.debug:logWarn("actor", "the function SpritedActor:getSpriteScalling is deprecated, prefer SpritedActor.sprite:getScalling()")
|
||||
core.debug:warning("actor", "the function SpritedActor:getSpriteScalling is deprecated, prefer SpritedActor.sprite:getScalling()")
|
||||
return self.sprite:getScalling()
|
||||
end
|
||||
|
||||
function SpritedActor:getFrame()
|
||||
if (self.sprite ~= nil) then
|
||||
core.debug:logWarn("actor", "the function SpritedActor:getFrame is deprecated, prefer SpritedActor.sprite:getFrame()")
|
||||
core.debug:warning("actor", "the function SpritedActor:getFrame is deprecated, prefer SpritedActor.sprite:getFrame()")
|
||||
return self.sprite:getFrame()
|
||||
end
|
||||
end
|
||||
|
||||
function SpritedActor:getRelativeFrame()
|
||||
if (self.sprite ~= nil) then
|
||||
core.debug:logWarn("actor", "the function SpritedActor:getRelativeFrame is deprecated, prefer SpritedActor.sprite:getRelativeFrame()")
|
||||
core.debug:warning("actor", "the function SpritedActor:getRelativeFrame is deprecated, prefer SpritedActor.sprite:getRelativeFrame()")
|
||||
return self.sprite:getRelativeFrame()
|
||||
end
|
||||
end
|
||||
|
||||
function SpritedActor:getAnimationDuration()
|
||||
if (self.sprite ~= nil) then
|
||||
core.debug:logWarn("actor", "the function SpritedActor:getAnimationDuration is deprecated, prefer SpritedActor.sprite:getAnimationDuration()")
|
||||
core.debug:warning("actor", "the function SpritedActor:getAnimationDuration is deprecated, prefer SpritedActor.sprite:getAnimationDuration()")
|
||||
return self.sprite:getAnimationDuration()
|
||||
end
|
||||
end
|
||||
|
|
|
@ -23,16 +23,18 @@
|
|||
|
||||
local TimedActor = Object:extend()
|
||||
|
||||
local TweenManager = require "birb.classes.time"
|
||||
|
||||
-- TIMER FUNCTIONS
|
||||
-- Control the integrated timers of the actor
|
||||
|
||||
function TimedActor:initTimers()
|
||||
self.timers = core.modules.Timers(self)
|
||||
self.timers = TweenManager(self)
|
||||
self:addUpdateFunction(self.updateTimers)
|
||||
end
|
||||
|
||||
function TimedActor:addTimer(name, t)
|
||||
core.debug:logWarn("actor", "function actor:addTimer is deprecated, prefer actor.timers:newTimer")
|
||||
core.debug:warning("actor", "function actor:addTimer is deprecated, prefer actor.timers:newTimer")
|
||||
self.timers:newTimer(t, name)
|
||||
end
|
||||
|
||||
|
|
|
@ -37,7 +37,7 @@ end
|
|||
|
||||
function MappedBox:drawTextureContent()
|
||||
local tx, ty = self.x, self.y - (self.z + self.d)
|
||||
core.debug:logInfo("mappedbox", "getting map layers at position " .. tx .. ";" .. ty)
|
||||
core.debug:print("mappedbox", "getting map layers at position " .. tx .. ";" .. ty)
|
||||
love.graphics.push()
|
||||
love.graphics.origin()
|
||||
love.graphics.translate(math.floor(-tx), math.floor(-ty))
|
||||
|
|
|
@ -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:getWithType(topTexture, "texture")
|
||||
self.bottomTexture = owner.assets:getWithType(bottomTexture, "texture")
|
||||
self.topTexture = owner.assets.images[topTexture]
|
||||
self.bottomTexture = owner.assets.images[bottomTexture]
|
||||
|
||||
TexturedBox.super.new(self, owner, w, h, d)
|
||||
self.haveLine = false
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
]]
|
||||
|
||||
local Hitbox2D = Object:extend()
|
||||
local rectStructure = require "birb.structures.rect"
|
||||
|
||||
-- INIT FUNCTIONS
|
||||
-- Initialise the actor and its base functions
|
||||
|
@ -42,24 +43,6 @@ function Hitbox2D:new(owner, type, data, sx, sy, isSolid)
|
|||
self:register()
|
||||
end
|
||||
|
||||
function Hitbox2D:setFromData(data, sx, sy)
|
||||
local sx = sx or 0
|
||||
local sy = sy or 0
|
||||
|
||||
self.ox = data[1]
|
||||
self.oy = data[2]
|
||||
self.w = data[3]
|
||||
self.h = data[4]
|
||||
|
||||
if (sx < 0) then
|
||||
self.ox = self.owner.w - self.ox - self.w
|
||||
end
|
||||
|
||||
if (sy < 0) then
|
||||
self.oy = self.owner.h - self.oy - self.h
|
||||
end
|
||||
end
|
||||
|
||||
function Hitbox2D:advertiseAsMainHitbox()
|
||||
self.isMainHitBox = true
|
||||
end
|
||||
|
@ -72,6 +55,30 @@ function Hitbox2D:modify(ox, oy, w, h)
|
|||
self.h = h
|
||||
end
|
||||
|
||||
function Hitbox2D:setFromData(data, sx, sy)
|
||||
local rect = utils.table.parse(data, rectStructure)
|
||||
|
||||
self.ox = rect.x
|
||||
self.oy = rect.y
|
||||
self.w = rect.w
|
||||
self.h = rect.h
|
||||
|
||||
self:applyScale(sx, sy)
|
||||
end
|
||||
|
||||
function Hitbox2D:applyScale(sx, sy)
|
||||
local sx = sx or 1
|
||||
local sy = sy or 1
|
||||
|
||||
if (sx < 0) then
|
||||
self.ox = self.owner.w - self.ox - self.w
|
||||
end
|
||||
|
||||
if (sy < 0) then
|
||||
self.oy = self.owner.h - self.oy - self.h
|
||||
end
|
||||
end
|
||||
|
||||
function Hitbox2D:setDebugColor(r,g,b)
|
||||
self.debug = {}
|
||||
self.debug.r = r
|
||||
|
@ -123,13 +130,41 @@ end
|
|||
function Hitbox2D:checkCollisionAtPoint(dx, dy, filter)
|
||||
self:updatePosition()
|
||||
|
||||
local dx, dy = self.ox + dx, self.oy + dy
|
||||
local x, y, cols, colNumber = self.world:checkCollision(self, dx, dy, filter)
|
||||
local nx, ny = self.ox + dx, self.oy + dy
|
||||
if (self.owner.useTileCollision and self.world.map.supportTileCollision) then
|
||||
if (self:checkTileCollision(nx, self.y)) then
|
||||
nx = self.x
|
||||
local relx = dx - self.x
|
||||
for i = 1, math.ceil(math.abs(relx)), 1 do
|
||||
local nnx = self.x + i * utils.math.sign(relx)
|
||||
if (not self:checkTileCollision(nnx, self.y)) then
|
||||
nx = nnx
|
||||
end
|
||||
end
|
||||
self.owner.xsp = 0
|
||||
end
|
||||
if (self:checkTileCollision(self.x, ny)) then
|
||||
ny = self.y
|
||||
local rely = dy - self.y
|
||||
for i = 1, math.ceil(math.abs(rely)), 1 do
|
||||
local nny = self.y + i * utils.math.sign(rely)
|
||||
if (not self:checkTileCollision(self.x, nny)) then
|
||||
ny = nny
|
||||
end
|
||||
end
|
||||
self.owner.ysp = 0
|
||||
end
|
||||
end
|
||||
local x, y, cols, colNumber = self.world:checkCollisionAtPoint(self, nx, ny, filter)
|
||||
local newx, newy = self:getNewOwnerPosition(x, y)
|
||||
|
||||
return newx, newy, cols, colNumber
|
||||
end
|
||||
|
||||
function Hitbox2D:checkTileCollision(dx, dy)
|
||||
return self.world:haveTileTypeInRect(dx + 1, dy + 1, self.w - 2, self.h - 2, "solid")
|
||||
end
|
||||
|
||||
-- DRAW FUNCTIONS
|
||||
-- Just some debug function to draw hitbox
|
||||
|
||||
|
@ -137,8 +172,6 @@ function Hitbox2D:draw()
|
|||
local x, y = self:getPosition()
|
||||
love.graphics.setColor(self.debug.r, self.debug.g, self.debug.b, 1)
|
||||
utils.graphics.box(x, y, self.w, self.h)
|
||||
love.graphics.setColor(1, 1, 1, 1)
|
||||
love.graphics.points(x, y)
|
||||
utils.graphics.resetColor()
|
||||
end
|
||||
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
]]
|
||||
|
||||
local Hitbox3D = Object:extend()
|
||||
local boxStructure = require "birb.structures.box"
|
||||
|
||||
-- INIT FUNCTIONS
|
||||
-- Initialise the actor and its base functions
|
||||
|
@ -42,25 +43,6 @@ function Hitbox3D:new(owner, type, data, sx, sy, isSolid)
|
|||
self:register()
|
||||
end
|
||||
|
||||
function Hitbox3D:setFromData(data, sx, sy)
|
||||
local sx = sx or 0
|
||||
local sy = sy or 0
|
||||
|
||||
self.ox = data[1]
|
||||
self.oy = data[2]
|
||||
self.oz = data[3]
|
||||
self.w = data[4]
|
||||
self.h = data[5]
|
||||
self.d = data[6]
|
||||
|
||||
if (sx < 0) then
|
||||
self.ox = self.owner.w - self.ox - self.w
|
||||
end
|
||||
if (sy < 0) then
|
||||
self.oz = self.owner.d - self.oz - self.d
|
||||
end
|
||||
end
|
||||
|
||||
function Hitbox3D:advertiseAsMainHitbox()
|
||||
self.isMainHitBox = true
|
||||
end
|
||||
|
@ -75,6 +57,32 @@ function Hitbox3D:modify(ox, oy, oz, w, h, d)
|
|||
self.d = d
|
||||
end
|
||||
|
||||
function Hitbox3D:setFromData(data, sx, sy)
|
||||
local box = utils.table.parse(data, boxStructure)
|
||||
|
||||
self.ox = box.x
|
||||
self.oy = box.y
|
||||
self.oz = box.z
|
||||
self.w = box.w
|
||||
self.h = box.h
|
||||
self.d = box.d
|
||||
|
||||
self:applyScale(sx, sy)
|
||||
end
|
||||
|
||||
function Hitbox3D:applyScale(sx, sy)
|
||||
local sx = sx or 1
|
||||
local sy = sy or 1
|
||||
|
||||
if (sx < 0) then
|
||||
self.ox = self.owner.w - self.ox - self.w
|
||||
end
|
||||
|
||||
if (sy < 0) then
|
||||
self.oy = self.owner.h - self.oy - self.h
|
||||
end
|
||||
end
|
||||
|
||||
function Hitbox3D:setDebugColor(r,g,b)
|
||||
self.debug = {}
|
||||
self.debug.r = r
|
||||
|
@ -126,8 +134,8 @@ end
|
|||
function Hitbox3D:checkCollisionAtPoint(dx, dy, dz, filter)
|
||||
self:updatePosition()
|
||||
|
||||
local dx, dy = self.ox + dx, self.oy + dy, self.oz + dz
|
||||
local x, y, z, cols, colNumber = self.world:checkCollision(self, dx, dy, dz, filter)
|
||||
local dx, dy, dz = self.ox + dx, self.oy + dy, self.oz + dz
|
||||
local x, y, z, cols, colNumber = self.world:checkCollisionAtPoint(self, dx, dy, dz, filter)
|
||||
local newx, newy, newz = self:getNewOwnerPosition(x, y, z)
|
||||
|
||||
return newx, newy, newz, cols, colNumber
|
||||
|
|
|
@ -17,8 +17,7 @@ end
|
|||
|
||||
function Sprite:clone()
|
||||
if self.name ~= nil then
|
||||
local baseSprite = self.assets:getWithType(self.name, "sprite")
|
||||
self.spriteClone = baseSprite:clone()
|
||||
self.spriteClone = self.assets.sprites[self.name]:clone()
|
||||
self.spriteClone:setCallbackTarget(self.owner)
|
||||
end
|
||||
end
|
||||
|
@ -49,14 +48,16 @@ function Sprite:update(dt)
|
|||
end
|
||||
end
|
||||
|
||||
function Sprite:setScalling(sx, sy)
|
||||
if (sx ~= nil) then
|
||||
self.sx = sx
|
||||
end
|
||||
function Sprite:setScallingX(sx)
|
||||
local sx = sx or 1
|
||||
|
||||
self.sx = sx
|
||||
end
|
||||
|
||||
function Sprite:setScallingY(sy)
|
||||
local sy = sy or 1
|
||||
|
||||
if (sy ~= nil) then
|
||||
self.sy = sy
|
||||
end
|
||||
end
|
||||
|
||||
function Sprite:getCurrentAnimation()
|
||||
|
@ -111,8 +112,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
|
||||
local sprite = self.assets:getWithType(self.name, "sprite")
|
||||
sprite:drawAnimation(x, y, r, sx, sy, ox, oy, kx, ky)
|
||||
self.assets.sprites[self.name]:draw(x, y, r, sx, sy, ox, oy, kx, ky)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -102,17 +102,23 @@ function BaseWorld:initActors( )
|
|||
self.currentCreationID = 0
|
||||
end
|
||||
|
||||
function BaseWorld:newActor(name, x, y, z)
|
||||
function BaseWorld:newActor(name, x, y, z, properties, mapname)
|
||||
local debugstring = " at (" .. x .. ";" .. y .. ")."
|
||||
core.debug:logInfo("world2D", "adding actor " .. name .. debugstring)
|
||||
self.obj.index[name](self, x, y)
|
||||
core.debug:print("world2D", "adding actor " .. name .. debugstring)
|
||||
local actor = self.obj.index[name](self, x, y)
|
||||
if (mapname ~= nil) then
|
||||
actor.mapname = mapname
|
||||
end
|
||||
if (properties ~= nil) then
|
||||
actor:setProperties(properties)
|
||||
end
|
||||
end
|
||||
|
||||
function BaseWorld:newCollision(name, x, y, z, w, h, d)
|
||||
local debugstringpos = "at (" .. x .. ";" .. y .. ")"
|
||||
local debugstringsize = "size is (" .. w .. ";" .. h .. ")"
|
||||
local debugstring = " " .. debugstringpos .. ". " .. debugstringsize .. "."
|
||||
core.debug:logInfo("world2D", "creating collision " .. name .. debugstring)
|
||||
core.debug:print("world2D", "creating collision " .. name .. debugstring)
|
||||
self.obj.collisions[name](self, x, y, w, h)
|
||||
end
|
||||
|
||||
|
@ -202,7 +208,7 @@ function BaseWorld:moveActor(actor, x, y, filter)
|
|||
return x, y, {}, 0
|
||||
end
|
||||
|
||||
function BaseWorld:checkCollision(actor, x, y, filter)
|
||||
function BaseWorld:checkCollisionAtPoint(actor, x, y, filter)
|
||||
-- as the baseworld have no collision function, we return empty collision
|
||||
-- datas, but from the same type than bump2D will return
|
||||
return x, y, {}, 0
|
||||
|
@ -252,9 +258,10 @@ function BaseWorld:newPlayer(x, y, z)
|
|||
end
|
||||
|
||||
function BaseWorld:sendInputToPlayers(actor)
|
||||
for i, player in ipairs(self.players) do
|
||||
local keys = self.scene:getKeys(player.sourceid)
|
||||
player.actor:getInput(keys)
|
||||
for i,v in ipairs(self.players) do
|
||||
--TODO: make the player get from a selected source inputs
|
||||
local keys = self.scene.sources[v.sourceid].keys
|
||||
v.actor:getInput(keys)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -351,9 +358,11 @@ end
|
|||
-- All update functions
|
||||
|
||||
function BaseWorld:update(dt)
|
||||
if (core.screen:isActive()) then
|
||||
self:updateMap(dt)
|
||||
self:sendInputToPlayers(dt)
|
||||
self:updateActors(dt)
|
||||
end
|
||||
self.cameras:update(dt)
|
||||
end
|
||||
|
||||
|
@ -370,6 +379,19 @@ function BaseWorld:updateMap(dt)
|
|||
end
|
||||
end
|
||||
|
||||
function BaseWorld:getTileTypeAtPoint(x, y)
|
||||
if (self.map.getTileTypeAtPoint ~= nil) then
|
||||
return self.map:getTileTypeAtPoint(x, y)
|
||||
end
|
||||
end
|
||||
|
||||
function BaseWorld:haveTileTypeInRect(x, y, x2, y2, type)
|
||||
if (self.map.haveTileTypeInRect ~= nil) then
|
||||
return self.map:haveTileTypeInRect(x, y, x2, y2, type)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
-- DRAW FUNCTIONS
|
||||
-- All function to draw the map, world and actors
|
||||
|
||||
|
@ -378,13 +400,15 @@ function BaseWorld:draw(dt)
|
|||
local camNumber = self.cameras:getViewNumber()
|
||||
|
||||
if (camNumber == 0) then
|
||||
self:drawMap()
|
||||
self:drawLowerLayers()
|
||||
self:drawActors()
|
||||
self:drawUpperLayers()
|
||||
else
|
||||
for i=1, camNumber do
|
||||
self.cameras:attachView(i)
|
||||
self:drawMap(i)
|
||||
self:drawLowerLayers(i)
|
||||
self:drawActors(i)
|
||||
self:drawUpperLayers(i)
|
||||
self.cameras:detachView(i)
|
||||
end
|
||||
end
|
||||
|
@ -398,6 +422,18 @@ function BaseWorld:drawActors(id)
|
|||
end
|
||||
end
|
||||
|
||||
function BaseWorld:drawUpperLayers()
|
||||
if (self.map ~= nil) then
|
||||
self.map:drawUpperLayers()
|
||||
end
|
||||
end
|
||||
|
||||
function BaseWorld:drawLowerLayers()
|
||||
if (self.map ~= nil) then
|
||||
self.map:drawLowerLayers()
|
||||
end
|
||||
end
|
||||
|
||||
function BaseWorld:drawMap(id)
|
||||
if (self.map ~= nil) then
|
||||
self.map:draw()
|
||||
|
|
|
@ -50,7 +50,7 @@ end
|
|||
|
||||
function CameraSystem:setMode(mode)
|
||||
self.mode = mode
|
||||
core.debug:logInfo("camera", "mode is now set to " .. mode)
|
||||
core.debug:print("camera", "mode is now set to " .. mode)
|
||||
return mode
|
||||
end
|
||||
|
||||
|
@ -178,15 +178,17 @@ function CameraSystem:attachView(id)
|
|||
self.current_canvas = love.graphics.getCanvas()
|
||||
love.graphics.setCanvas(view.canvas)
|
||||
love.graphics.clear()
|
||||
|
||||
local tx, ty, scale
|
||||
if id ~= nil then
|
||||
-- Du à la manière dont fonctionne STI, on est obligé de récupérer les info
|
||||
-- de position de camera pour afficher la carte par rapport à ces infos
|
||||
local tx, ty = self:getViewCoordinate(id)
|
||||
local scale = self:getViewScale(id) or 1
|
||||
tx, ty = self:getViewCoordinate(id)
|
||||
scale = self:getViewScale(id) or 1
|
||||
tx = math.floor(tx) * -1
|
||||
ty = math.floor(ty) * -1
|
||||
|
||||
local w, h = core.screen:getDimensions()
|
||||
end
|
||||
|
||||
love.graphics.push()
|
||||
love.graphics.origin()
|
||||
|
@ -212,7 +214,6 @@ function CameraSystem:detachView(id)
|
|||
|
||||
local unscale = 1 / view.scale
|
||||
love.graphics.scale(unscale, unscale)
|
||||
self:drawHUD(id)
|
||||
|
||||
love.graphics.pop()
|
||||
end
|
||||
|
@ -385,15 +386,4 @@ function CameraSystem:followAllActors(id)
|
|||
end
|
||||
end
|
||||
|
||||
|
||||
-- DRAW FUNCTIONS
|
||||
-- Basic callback to draw stuff
|
||||
|
||||
function CameraSystem:drawHUD(id)
|
||||
local view = self:getView(id)
|
||||
local viewx, viewy, vieww, viewh = self:getOnScreenViewCoordinate(id)
|
||||
|
||||
view.target:drawHUD(id, vieww, viewh)
|
||||
end
|
||||
|
||||
return CameraSystem
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue