fork core from latest imperium-porcorum version

This commit is contained in:
Kazhnuz 2019-03-16 12:27:38 +01:00
parent 974bfae46d
commit fa7306efde
24 changed files with 2585 additions and 0 deletions

38
debug.lua Normal file
View file

@ -0,0 +1,38 @@
-- core/debug.lua :: Debug functions for the core system.
--[[
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 DebugSystem = Object:extend()
local lovebird = require("libs.lovebird")
function DebugSystem:new(controller, active)
self.controller = controller
lovebird.update()
self.active = active or false
end
function DebugSystem:update(dt)
lovebird.update(dt)
end
return DebugSystem

71
init.lua Normal file
View file

@ -0,0 +1,71 @@
-- core/init.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 © 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 CoreSystem = Object:extend()
local DebugSystem = require "core.debug"
local Options = require "core.options"
local Input = require "core.input"
local Screen = require "core.screen"
local Lang = require "core.lang"
local SceneManager= require "core.scenemanager"
function CoreSystem:new()
self.debug = DebugSystem(self)
self.options = Options(self)
self.input = Input(self)
self.screen = Screen(self)
self.scenemanager = SceneManager(self)
end
function CoreSystem:mousemoved(x, y, dx, dy)
local x, y = self.screen:project(x, y)
local dx, dy = self.screen:project(dx, dy)
self.scenemanager:mousemoved(x, y, dx, dy)
end
function CoreSystem:mousepressed( x, y, button, istouch )
local x, y = self.screen:project(x, y)
self.scenemanager:mousepressed( x, y, button, istouch )
end
function CoreSystem:update(dt)
self.debug:update(dt)
self.input:update(dt)
self.scenemanager:update(dt)
end
function CoreSystem:draw()
self.scenemanager:draw()
end
function CoreSystem:exit()
self.options:save()
love.event.quit()
end
return CoreSystem

117
input.lua Normal file
View file

@ -0,0 +1,117 @@
-- core/input.lua :: The input system. This object take care of transforming the
-- differents inputs source in a virtual controller for the game.
--[[
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 InputManager = Object:extend()
function InputManager:new(controller)
self.controller = controller
self.data = self.controller.options.data.input[1]
self.keys = self:getKeyList()
self.fakekeys = self:getKeyList()
end
function InputManager:isDown(padkey)
local isdown = false
if self.data.type == "keyboard" then
local key = self.data.keys[padkey]
isdown = love.keyboard.isDown(key)
if isdown then
end
else
print("Warning: unsupported input device")
end
return isdown
end
function InputManager:getKeyList()
local keys = {}
for k,v in pairs(self.data.keys) do
keys[k] = {}
keys[k].isDown = false
keys[k].isPressed = false
keys[k].isReleased = false
keys[k].test = "ok"
end
return keys
end
function InputManager:translateAction(key)
--TODO:depreciated function
local padkey = ""
for k,v in pairs(self.data.keys) do
if v == key then padkey = k end
end
return padkey
end
function InputManager:getKey(padkey)
local padkey = padkey
for k,v in pairs(self.data.keys) do
if (k == padkey) then key = v end
end
return key
end
function InputManager:flushKeys()
self.keys = {}
for k,v in pairs(self.data.keys) do
self.keys[k] = {}
self.keys[k].isDown = false
self.keys[k].isPressed = false
self.keys[k].isReleased = false
self.keys[k].test = "ok"
end
end
function InputManager:update(dt)
for k,v in pairs(self.keys) do
local isDown = self:isDown(k)
if (isDown) then
if not (self.keys[k].isDown) then
self.keys[k].isDown = true
self.keys[k].isPressed = true
self.keys[k].isReleased = false
else
if (self.keys[k].isPressed) then
self.keys[k].isPressed = false
end
end
else
if (self.keys[k].isDown) then
self.keys[k].isDown = false
self.keys[k].isPressed = false
self.keys[k].isReleased = true
else
if (self.keys[k].isReleased) then
self.keys[k].isReleased = false
end
end
end
end
end
return InputManager

52
lang.lua Normal file
View file

@ -0,0 +1,52 @@
-- core/langs.lua :: The translation system. Transform a string to another
-- according to the translations files in the datas/ folder.
--[[
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 LanguageManager = Object:extend()
local langs = require "datas.languages"
function LanguageManager:new(controller)
self.controller = controller
self:setLang(self.controller.options.data.language)
end
function LanguageManager:getStringList(library, file)
return require(self.lang .. "." .. library .. "." .. file)
end
function LanguageManager:getLangName(lang)
local langnames = langs.available_langs
return langnames[lang]
end
function LanguageManager:getCurrentLangName()
local langnames = langs.available_langs
return langnames[self.lang]
end
function LanguageManager:setLang(lang)
self.controller.options.data.language = lang
self.lang = self.controller.options.data.language
end
return LanguageManager

101
modules/assets/animator.lua Normal file
View file

@ -0,0 +1,101 @@
-- assets/animator :: the animator object. The animator object handle what
-- frame a sprite should draw.
--[[
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 Animator = Object:extend()
function Animator:new(sprite)
self.sprite = sprite
self.frame = 1
self.frameTimer = 0
self.currentAnimation = ""
self.animationData = {}
self.customSpeed = 0
self:changeToDefaultAnimation()
end
function Animator:setCustomSpeed(customSpeed)
self.customSpeed = customSpeed or 0
end
function Animator:update(dt)
if (self.currentAnimation == "") then
print("warning: no current animation data")
return 0
end
local speed = self.animationData.speed
if (self.animationData.speed) == -1 then
speed = self.customSpeed --math.abs(self.xsp / 16)
end
self.frameTimer = self.frameTimer + (speed * dt)
if self.frameTimer > 1 then
self.frameTimer = 0
if self.frame == self.animationData.endAt then
self.frame = self.animationData.loop
else
self.frame = self.frame + 1
end
end
end
function Animator:getAnimationDuration(animation)
return (self.animationData.endAt - self.animationData.startAt) / self.animationData.speed
end
function Animator:getFrame()
return self.frame
end
function Animator:animationExist(name)
return (self.sprite.data.animations[self.currentAnimation] ~= nil)
end
function Animator:draw(x, y, r, sx, sy, ox, oy, kx, ky)
self.sprite:drawFrame(self.frame, x, y, r, sx, sy, ox, oy, kx, ky)
end
function Animator:changeAnimation(name, restart)
-- Force restart if animation name is different
if (self.currentAnimation ~= name) then
restart = true
else
restart = restart or false
end
self.currentAnimation = name
self.animationData = self.sprite.data.animations[self.currentAnimation]
if (restart == true) then
self.frame = self.animationData.startAt
self.frameTimer = 0
end
end
function Animator:changeToDefaultAnimation(restart)
self:changeAnimation(self.sprite.data.metadata.defaultAnim, restart)
end
return Animator

110
modules/assets/autotile.lua Normal file
View file

@ -0,0 +1,110 @@
-- assets/autotile :: The autotile object : this is an object that draw tiles
-- automatically with borders in rectangles.
-- It works with a 3×3 tileset showing all borders.
--[[
Copyright © 2019 Kazhnuz
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
]]
local Tileset = require "core.modules.assets.tileset"
local Autotile = Object:extend()
function Autotile:new(filepath)
self.tileset = Tileset(filepath)
self.data = require(filepath .. ".lua")
self.metadata = self.data.metadata
self.tilesize = self.metadata.width
end
function Autotile:drawtile(i, j, x, y, r, sx, sy, ox, oy, kx, ky)
local i = i or 1
local j = j or 1
local tilesize = self.tilesize / 2
i = (i - 1) * 2 + 1
j = (j - 1) * 2 + 1
self.tileset:drawTile_Grid(i , j , x , y , r, sx, sy, ox, oy, kx, ky)
self.tileset:drawTile_Grid(i + 1, j , x + tilesize, y , r, sx, sy, ox, oy, kx, ky)
self.tileset:drawTile_Grid(i , j + 1, x , y + tilesize, r, sx, sy, ox, oy, kx, ky)
self.tileset:drawTile_Grid(i + 1, j + 1, x + tilesize, y + tilesize, r, sx, sy, ox, oy, kx, ky)
end
function Autotile:draw(x, y, w, h)
local w = w or self.tilesize
local h = h or self.tilesize
w = math.max(math.floor(w / self.tilesize), 1)
h = math.max(math.floor(h / self.tilesize), 1)
local halfsize = self.tilesize / 2
local tilesize = self.tilesize
if (w == 1) then
self.tileset:drawtile_Grid(1, 1, x , y)
self.tileset:drawtile_Grid(1, 6, x , y + (h*2 - 1) * halfsize)
self.tileset:drawtile_Grid(6, 1, x + (w*2 - 1) * halfsize, y)
self.tileset:drawtile_Grid(6, 6, x + (w*2 - 1) * halfsize, y + (h*2 - 1) * halfsize)
if (h > 1) then
h = h - 1
for i = 1, h do
self.tileset:drawtile_Grid(1, 3, x, y + (i * tilesize) - halfsize)
self.tileset:drawtile_Grid(6, 3, x + halfsize, y + (i * tilesize) - halfsize)
self.tileset:drawtile_Grid(1, 4, x , y + (i * tilesize))
self.tileset:drawtile_Grid(6, 4, x + halfsize, y + (i * tilesize))
end
end
-- draw just one stuff
else
if (h == 1) then
self.tileset:drawtile_Grid(1, 1, x , y)
self.tileset:drawtile_Grid(1, 6, x , y + (h*2 - 1) * halfsize)
self.tileset:drawtile_Grid(6, 1, x + (w*2 - 1) * halfsize, y)
self.tileset:drawtile_Grid(6, 6, x + (w*2 - 1) * halfsize, y + (h*2 - 1) * halfsize)
w = w - 1
for i = 1, w do
self.tileset:drawtile_Grid(3, 1, x + (i * tilesize) - halfsize, y)
self.tileset:drawtile_Grid(3, 6, x + (i * tilesize) - halfsize, y + halfsize)
self.tileset:drawtile_Grid(4, 1, x + (i * tilesize) , y )
self.tileset:drawtile_Grid(4, 6, x + (i * tilesize), y +halfsize)
end
else
self:drawtile(1, 1, x , y)
self:drawtile(1, 3, x , y + (h - 1) * tilesize)
self:drawtile(3, 1, x + (w - 1) * tilesize, y)
self:drawtile(3, 3, x + (w - 1) * tilesize, y + (h - 1) * tilesize)
w = w - 2
h = h - 2
for i=1, w do
self:drawtile(2, 1, i * tilesize, y)
self:drawtile(2, 3, i * tilesize, y + (h + 1) * tilesize)
for j=1, h do
self:drawtile(2, 2, i * tilesize, j * tilesize)
end
end
for i=1, h do
self:drawtile(1, 2, x , i * tilesize)
self:drawtile(3, 2, x + (w + 1) * tilesize, i * tilesize)
end
end
end
end
return Autotile

View file

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

178
modules/assets/fonts.lua Normal file
View file

@ -0,0 +1,178 @@
-- assets/fonts :: the fonts object, which is a simple way to draw text with font.
-- Some of these functions are quite slow, so it's better to use them to generate
-- texture instead of text.
--[[
Copyright © 2019 Kazhnuz
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
]]
local Font = Object:extend()
-- Initilizing and configuring option
function Font:new(filename, size)
local filename = filename
self.font = love.graphics.newFont(filename, size)
self.filter = ""
self:setColor(1, 1, 1, 1)
self:setSpacing(false, 0)
self.align = "left"
end
function Font:set()
love.graphics.setFont(self.font)
end
function Font:setColor(r, g, b, a)
self.color = {}
self.color.r = r
self.color.g = g
self.color.b = b
self.color.a = a
end
function Font:setColorFromTable(color)
self.color = color
end
function Font:setSpacing(use_custom, size)
self.spacing = {}
self.spacing.active = use_custom
self.spacing.size = size
end
function Font:setAlign(align)
self.align = align
end
function Font:setFilter(filter)
self.filter = filter
end
function Font:setLineHeight(height)
self.font:setLineHeight(height)
end
-- get information functions
function Font:getHeight()
local font = self.font
return font:getHeight()
end
function Font:getWidth(string)
local spacing = 0
if (self.spacing.active == true) then
local charNumber = string.len(string)
spacing = self.spacing.size * charNumber
end
local width = self.font:getWidth(string) + spacing
return width
end
function Font:getColor()
return self.color
end
-- print functions
function Font:draw(text, x, y, limit, align, r, sx, sy, ox, oy, kx, ky)
-- draw text with color and effect applied
local limit = limit or 0
local align = align or self.align
self:applyFilter(text, x, y, limit, align, r, sx, sy, ox, oy, kx, ky)
love.graphics.setColor(self.color.r, self.color.g, self.color.b, self.color.a)
self:printf(text, x, y, limit, align, r, sx, sy, ox, oy, kx, ky)
end
function Font:print(text, x, y, align, r, sx, sy, ox, oy, kx, ky)
self:set()
if (self.spacing.active) then
utils.graphics.printWithSpacing(text, x, y, self.spacing.size, align, r, sx, sy, ox, oy, kx, ky)
else
utils.graphics.print(text, x, y, align, r, sx, sy, ox, oy, kx, ky)
end
end
function Font:printf(text, x, y, limit, align, r, sx, sy, ox, oy, kx, ky)
self:set()
if (limit > 0) then
love.graphics.printf(text, x, y, limit, align, r, sx, sy, ox, oy, kx, ky)
else
self:print(text, x, y, align, r, sx, sy, ox, oy, kx, ky)
end
end
-- FILTER SYSTEM
function Font:applyFilter(text, x, y, limit, align, r, sx, sy, ox, oy, kx, ky)
if self.filter == "shadow" then
self:applyFilterShadow(text, x, y, limit, align, r, sx, sy, ox, oy, kx, ky)
elseif self.filter == "border" then
self:applyFilterBorder(text, x, y, limit, align, r, sx, sy, ox, oy, kx, ky)
elseif self.filter == "doubleborder" then
self:applyFilterDoubleBorder(text, x, y, limit, align, r, sx, sy, ox, oy, kx, ky)
end
end
function Font:applyFilterShadow(text, x, y, limit, align, r, sx, sy, ox, oy, kx, ky)
love.graphics.setColor(0, 0, 0, 1)
self:printf(text, x+1, y+1, limit, align, align, r, sx, sy, ox, oy, kx, ky)
utils.graphics.resetColor()
end
function Font:applyFilterBorder(text, x, y, limit, align, r, sx, sy, ox, oy, kx, ky)
love.graphics.setColor(0, 0, 0, 1)
self:printf(text, x-1, y-1, limit, align, r, sx, sy, ox, oy, kx, ky)
self:printf(text, x , y-1, limit, align, r, sx, sy, ox, oy, kx, ky)
self:printf(text, x+1, y-1, limit, align, r, sx, sy, ox, oy, kx, ky)
self:printf(text, x+1, y , limit, align, r, sx, sy, ox, oy, kx, ky)
self:printf(text, x-1, y , limit, align, r, sx, sy, ox, oy, kx, ky)
self:printf(text, x-1, y+1, limit, align, r, sx, sy, ox, oy, kx, ky)
self:printf(text, x , y+1, limit, align, r, sx, sy, ox, oy, kx, ky)
self:printf(text, x+1, y+1, limit, align, r, sx, sy, ox, oy, kx, ky)
utils.graphics.resetColor()
end
function Font:applyFilterDoubleBorder(text, x, y, limit, align, r, sx, sy, ox, oy, kx, ky)
love.graphics.setColor(0, 0, 0, 1)
self:printf(text, x-2, y-2, limit, align, r, sx, sy, ox, oy, kx, ky)
self:printf(text, x , y-2, limit, align, r, sx, sy, ox, oy, kx, ky)
self:printf(text, x+2, y-2, limit, align, r, sx, sy, ox, oy, kx, ky)
self:printf(text, x+2, y , limit, align, r, sx, sy, ox, oy, kx, ky)
self:printf(text, x-2, y , limit, align, r, sx, sy, ox, oy, kx, ky)
self:printf(text, x-2, y+2, limit, align, r, sx, sy, ox, oy, kx, ky)
self:printf(text, x , y+2, limit, align, r, sx, sy, ox, oy, kx, ky)
self:printf(text, x+2, y+2, limit, align, r, sx, sy, ox, oy, kx, ky)
utils.graphics.resetColor()
end
return Font

View file

@ -0,0 +1,14 @@
local Font = require "core.modules.assets.fonts"
local ImageFont = Font:extend()
function ImageFont:new(filename, extraspacing)
local data = require(filename)
local extraspacing = extraspacing or data.extraspacing or 1
self.font = love.graphics.newImageFont(filename .. ".png", data.glyphs, extraspacing)
self.filter = ""
self:setColor(1, 1, 1, 1)
self:setSpacing(false, 0)
self.align = "left"
end
return ImageFont

198
modules/assets/init.lua Normal file
View file

@ -0,0 +1,198 @@
-- modules/assets :: a simple assets manager, aim to put every assets in a simple
-- serie of table in order to find them easily.
--[[
Copyright © 2019 Kazhnuz
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
]]
local Assets = Object:extend()
local Sprite = require "core.modules.assets.sprites"
local Font = require "core.modules.assets.fonts"
local ImageFont = require "core.modules.assets.imagefonts"
local Tileset = require "core.modules.assets.tileset"
local Autotile = require "core.modules.assets.autotile"
local Background = require "core.modules.assets.background"
function Assets:new()
self.sprites = {}
self.sfx = {}
self.fonts = {}
self.music = nil
self:clearBackgrounds()
self:clearFonts()
self:clearAutotile()
self:clearTileset()
self.images = {}
self.isActive = true
end
function Assets:init()
self.sprites = {}
self.sfx = {}
self.fonts = {}
self.music = nil
self.backgrounds= {}
self:clearFonts()
self.images = {}
end
function Assets:clear()
-- TODO: destroy individually each texture/image when assets are cleared
self.sprites = {}
self.sfx = {}
self.fonts = {}
self.music = nil
self.backgrounds= {}
self:clearFonts()
self.images = {}
end
function Assets:update(dt)
if (self.isActive) then
self:animationsUpdate(dt)
end
end
-- SFX et Musique
function Assets:addSFX(name, filepath)
self:newSFX(name, filepath)
end
function Assets:newSFX(name, filepath)
self.sfx[name] = love.audio.newSource( filepath, "static" )
end
function Assets:clearSFX()
love.audio.stop( )
self.sfx = {}
end
function Assets:setMusic(filename)
if filename ~= nil then
love.audio.stop( )
self.music = love.audio.newSource(filename, "stream" )
self.music:setVolume(core.options.data.audio.music / 100)
end
end
function Assets:playSFX(filename)
if not (self.sfx[filename] == nil) then
self.sfx[filename]:stop()
self.sfx[filename]:setVolume(core.options.data.audio.sfx / 100)
love.audio.play( self.sfx[filename] )
end
end
function Assets:playMusic()
if not (self.music == nil) then
love.audio.play(self.music)
end
end
function Assets:silence()
love.audio.stop()
end
-- Background --
function Assets:addImage(name, filename)
self.images[name] = love.graphics.newImage(filename)
end
function Assets:drawImage(name, x, y, r, sx, sy, ox, oy, kx, ky)
love.graphics.draw(self.images[name], x, y, r, sx, sy, ox, oy, kx, ky)
end
-- Images --
function Assets:clearBackgrounds()
self.backgrounds = {}
end
function Assets:addBackground(name, filepath)
self.backgrounds[name] = Background(filepath)
end
-- SPRITES --
function Assets:addSprite(name, filepath)
self.sprites[name] = Sprite(filepath)
end
function Assets:clearSprites()
self.sprites = {}
end
function Assets:animationsUpdate(dt)
for i,v in pairs(self.sprites) do
v:update(dt)
end
end
-- FONTS --
function Assets:clearFonts()
self.fonts = {}
end
function Assets:addFont(key, filename, size)
local font = Font(filename, size)
self.fonts[key] = font
end
function Assets:addImageFont(key, filename, extraspacing)
local font = ImageFont(filename, extraspacing)
self.fonts[key] = font
end
function Assets:getFont(filename)
return self.fonts[filename]
end
-- Tileset
function Assets:addTileset(name, filepath)
self.tileset[name] = Tileset(filepath)
end
function Assets:clearTileset()
self.tileset = {}
end
-- Autotile
function Assets:addAutotile(name, tilesize)
self.autotile[name] = Autotile(name, tilesize)
end
function Assets:clearAutotile()
self.autotile = {}
end
return Assets

View file

@ -0,0 +1,86 @@
-- assets/sprite :: the assets object, which is basically a tileset animated by
-- an animator object. An animator object is always tied to a sprite, but a sprite
-- can use different animator in order to make several animator share the same sprite
--[[
Copyright © 2019 Kazhnuz
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
]]
local Sprite = Object:extend()
local Animator = require("core.modules.assets.animator")
local Tileset = require("core.modules.assets.tileset")
function Sprite:new(filepath)
self.tileset = Tileset(filepath)
self.data = require(filepath)
self.animator = Animator(self)
self.customSpeed = 0
self:changeToDefaultAnimation(true)
end
function Sprite:update(dt)
self.animator:update(dt)
end
function Sprite:clone()
return Animator(self)
end
function Sprite:setCustomSpeed(customSpeed)
self.animator:setCustomSpeed(customSpeed)
end
function Sprite:changeToDefaultAnimation(restart)
self.animator:changeToDefaultAnimation(restart)
end
function Sprite:changeAnimation(name, restart)
self.animator:changeAnimation(name, restart)
end
function Sprite:animationExist(name)
return self.animator:animationExist(name)
end
function Sprite:drawAnimation(x, y, r, sx, sy, ox, oy, kx, ky)
self.animator:draw(x, y, r, sx, sy, ox, oy, kx, ky)
end
function Sprite:drawFrame(frame, x, y, r, sx, sy, ox, oy, kx, ky)
self.tileset:drawTile(frame, x, y, r, sx, sy, ox, oy, kx, ky)
end
function Sprite:drawPart(x, y, w, h, r, sx, sy, ox, oy, kx, ky)
local w = math.floor(w)
local h = math.floor(h)
if w >= 0 and h <= 0 then
return 0
end
love.graphics.setScissor(x - ox, y - oy, w, h)
self:drawAnimation(x, y, r, sx, sy, ox, oy, kx, ky)
love.graphics.setScissor( )
end
return Sprite

View file

@ -0,0 +1,89 @@
-- assets/tileset :: tileset are automatic breakage of texture into quads. they
-- have the adventage of being automatized, reducing the ammount of code needed
-- to create quads.
-- They have two manners to be draw: with their quad id (in 1D) or by using their
-- place in the grid, in 2D.
--[[
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 Tileset = Object:extend()
function Tileset:new(filepath)
self.texture = love.graphics.newImage(filepath .. ".png")
local data = require(filepath)
self.metadata = data.metadata
self:createQuads()
end
function Tileset:createGrid()
self.textureWidth, self.textureHeight = self.texture:getDimensions()
self.width, self.height = self.metadata.width, self.metadata.height
self.gridWidth, self.gridHeight = math.floor(self.textureWidth / self.width),
math.floor(self.textureHeight / self.height)
end
function Tileset:createQuads()
self.quads = {}
self:createGrid()
local quad, n
n = 1
for i=0, (self.gridHeight-1) do
for j=0, (self.gridWidth-1) do
quad = love.graphics.newQuad(j * self.width, i * self.height, self.width, self.height, self.textureWidth, self.textureHeight)
self.quads[n] = quad
n = n + 1
end
end
end
function Tileset:getTileID_Grid(x, y)
local n = (y - 1) * self.gridWidth + x
return n
end
function Tileset:getTile_Grid(x, y)
return self:getTile(self:getTileID_Grid(x, y))
end
function Tileset:getTile(n)
return self.quads[n]
end
function Tileset:drawTile_Grid(i, j, x, y, r, sx, sy, ox, oy, kx, ky)
local tileID = self:getTileID_Grid(i, j)
love.graphics.draw(self.texture, self.quads[tileID], x, y, r, sx, sy, ox, oy, kx, ky)
end
function Tileset:drawTile(id, x, y, r, sx, sy, ox, oy, kx, ky)
love.graphics.draw(self.texture, self.quads[id], x, y, r, sx, sy, ox, oy, kx, ky)
end
return Tileset

View file

@ -0,0 +1,186 @@
local cwd = (...):gsub('%.flowbox$', '') .. "."
local Menu = require(cwd .. "parent")
local FlowBox = Menu:extend()
local menuutils = require(cwd .. "widgets.utils")
function FlowBox:new(menusystem, name, x, y, w, h, slots_hor, slots_vert)
self.view = {}
self.view.slotNumber = slots_hor * slots_vert
self.view.lineNumber = slots_vert
self.view.colNumber = slots_hor
self.view.firstSlot = 1
FlowBox.super.new(self, menusystem, name, x, y, w, h)
self.widget.h = math.floor( self.h / slots_vert )
self.widget.w = math.floor( self.w / slots_hor )
self.h = slots_vert * self.widget.h -- On fait en sorte que la hauteur
self.w = slots_hor * self.widget.w -- et la largeur
-- soit un multiple du nombre de slot et de leur dimensions
end
function FlowBox:updateWidgetSize()
self.widget.h = math.floor( self.h / self.view.lineNumber )
self.widget.w = math.floor( self.w / self.view.colNumber )
end
function FlowBox:update(dt)
self:updateView()
end
function FlowBox:updateView()
local col, line = self:getCoord(self.widget.selected)
local begincol, beginline = self:getCoord(self.view.firstSlot)
if line < beginline then
beginline = line
end
if line > beginline + self.view.lineNumber - 1 then
beginline = line - self.view.lineNumber + 1
end
if beginline < 0 then
beginline = 0
end
self.view.firstSlot = beginline * self.view.colNumber + 1
end
function FlowBox:getCoord(id_selected)
id_selected = id_selected - 1 -- On simplifie les calcul en prenant 0 comme départ
local line, col
line = math.floor(id_selected / self.view.colNumber)
col = id_selected - (line * self.view.colNumber)
return col, line
end
function FlowBox:moveCursor(new_col, new_line)
local col, line = self:getCoord(self.widget.selected)
local lastcol, lastline = self:getCoord(#self.widget.list)
if new_line < 0 then
new_line = lastline
end
if new_line > lastline then
new_line = 0
end
if (new_line == lastline) then
if new_col < 0 then
new_col = lastcol
end
if new_col > lastcol then
if (line == lastline) then
new_col = 0
else
new_col = lastcol
end
end
else
if new_col < 0 then
new_col = self.view.colNumber - 1
end
if new_col == self.view.colNumber then
new_col = 0
end
end
self.widget.selected = (new_line * self.view.colNumber) + new_col + 1
end
function FlowBox:keyreleased(key, code)
local col, line = self:getCoord(self.widget.selected)
if key == 'left' then
self:moveCursor(col - 1, line)
end
if key == 'right' then
self:moveCursor(col + 1, line)
end
if key == 'up' then
self:moveCursor(col, line - 1)
end
if key == 'down' then
self:moveCursor(col, line + 1)
end
if key == "A" then
if (self.widget.selected >= 1 and self.widget.selected <= #self.widget.list) then
self.widget.list[self.widget.selected]:action()
end
end
end
function FlowBox:mousemoved(x, y)
local col, line = self:getCoord(self.widget.selected)
local begincol, beginline = self:getCoord(self.view.firstSlot)
local newcol, newline, widget_selected
newline = beginline + math.floor(y / self.widget.h)
newcol = math.floor(x / self.widget.w)
widget_selected = (newline * self.view.colNumber) + newcol + 1
if widget_selected >= 1 and widget_selected <= #self.widget.list then
self.widget.selected = widget_selected
self:getFocus()
end
end
function FlowBox:mousepressed(x, y, button, isTouch)
local col, line = self:getCoord(self.widget.selected)
local begincol, beginline = self:getCoord(self.view.firstSlot)
local newline, newcol, widget_selected
newline = beginline + math.floor(y / self.widget.h)
newcol = math.floor(x / self.widget.w)
widget_selected = (newline * self.view.colNumber) + newcol + 1
if widget_selected >= 1 and widget_selected <= #self.widget.list then
self.widget.selected = widget_selected
self:getFocus()
self.widget.list[self.widget.selected]:action()
end
end
function FlowBox:draw()
self:updateView()
local widgety = self.y
local widgetx = self.x
for i,v in ipairs(self.widget.list) do
if (i >= self.view.firstSlot) and (i < self.view.firstSlot + self.view.slotNumber) then
v:draw(widgetx, widgety, self.widget.w, self.widget.h)
if self.widget.selected == i and self:haveFocus() == true then
v:drawSelected(widgetx, widgety, self.widget.w, self.widget.h)
else
v:draw(widgetx, widgety, self.widget.w, self.widget.h)
end
widgetx = widgetx + self.widget.w
if widgetx == (self.x + self.w) then
widgetx = self.x
widgety = widgety + self.widget.h
end
end
end
end
function FlowBox:drawCursor()
self:updateView()
local begincol, beginline = self:getCoord(self.view.firstSlot)
if (self.widget.selected >= 1 and self.widget.selected <= #self.widget.list) then
local w, h = self:getWidgetSize()
local col, line = self:getCoord(self.widget.selected)
local x = (col) * h
local y = (line - beginline) * h
menuutils.drawCursor(self.x + x, self.y + y, w, h)
end
end
return FlowBox

235
modules/menusystem/grid.lua Normal file
View file

@ -0,0 +1,235 @@
local cwd = (...):gsub('%.grid$', '') .. "."
local Menu = require(cwd .. "parent")
local GridBox = Menu:extend()
local menuutils = require(cwd .. "widgets.utils")
function GridBox:new(menusystem, name, x, y, w, h, colNumber, lineNumber)
self.view = {}
self.view.slotNumber = colNumber * lineNumber
self.view.colNumber = colNumber
self.view.lineNumber = lineNumber
self.view.firstSlot = 1
GridBox.super.new(self, menusystem, name, x, y, w, h)
self.h = lineNumber * self.widget.h -- On fait en sorte que la hauteur
self.w = colNumber * self.widget.w -- et la largeur
-- soit un multiple du nombre de slot et de leur dimensions
self.cursor = {}
self.cursor.x = 0
self.cursor.y = 0
-- La gridbox possède la particularité de pouvoir fusioner des slots, on fait
-- donc une liste de slots disponibles, qui serviront par la suite.
self.slots = {}
end
function GridBox:addSlot(widgetID, x, y, w, h)
local slot = {}
slot.x = x
slot.y = y
slot.w = w
slot.h = h
slot.widgetID = widgetID
table.insert(self.slots, slot)
end
function GridBox:updateWidgetSize()
self.widget.h = math.floor( self.h / self.view.lineNumber )
self.widget.w = math.floor( self.w / self.view.colNumber )
end
function GridBox:getWidgetSize(id)
local slot = self:getWidgetSlot(id)
if slot == 0 then
return 1, 1
else
return self.widget.w * self.slots[slot].w, self.widget.h * self.slots[slot].h
end
end
function GridBox:getSlotHitbox(slot)
local x, y, w, h
x = self.slots[slot].x * self.widget.w
y = self.slots[slot].y * self.widget.h
w = self.slots[slot].w * self.widget.w
h = self.slots[slot].h * self.widget.h
return x, y, w, h
end
function GridBox:getSlotCenter(slot)
local x, y, w, h = self:getSlotHitbox(slot)
return x + (w/2), y + (h/2)
end
function GridBox:getWidgetID(slot)
local widgetID
if self.slots[slot] ~= nil then
widgetID = self.slots[slot].widgetID
else
widgetID = 0
end
return widgetID
end
function GridBox:haveWidget(slot)
local id = self:getWidgetID(slot)
return self.widget.list[id] ~= nil
end
function GridBox:getWidgetSlot(widgetID)
local slot = 0
for i,v in ipairs(self.slots) do
if (self.slots[i].widgetID == widgetID) then
slot = i
end
end
return slot
end
function GridBox:getWidgetAtPoint(x, y)
local x = x or 0
local y = y or 0
local widgetID = nil
for i,v in ipairs(self.slots) do
local xx, yy, ww, hh = self:getSlotHitbox(i)
if (x >= xx) and (y >= yy) and (x < xx + ww) and (y < yy + hh) then
widgetID = v.widgetID
end
end
return widgetID
end
function GridBox:update(dt)
self.view.firstSlot = 1
end
function GridBox:keyreleased(key, code)
slotID = self:getWidgetSlot(self.widget.selected)
local col, line = self.cursor.x, self.cursor.y
if key == 'left' then
self:moveCol(-1)
end
if key == 'right' then
self:moveCol(1)
end
if key == 'up' then
self:moveLine(-1)
end
if key == 'down' then
self:moveLine(1)
end
if key == "A" and self.widget.selected <= #self.widget.list then
self.widget.list[self.widget.selected]:action()
end
end
function GridBox:moveCol(direction)
local orig_x, orig_y = self:getSlotCenter(self.widget.selected)
local distance = self.w -- on met directement à la distance max possible le système
local nearastWidget = 0
for i,v in ipairs(self.slots) do
local xx, yy = self:getSlotCenter(i)
-- On commence par vérifier si le slot est bien positionné par rapport au
-- widget de base
if utils.math.sign(xx - orig_x) == direction then
if utils.math.pointDistance(orig_x, orig_y, xx, yy) < distance then
distance = utils.math.pointDistance(orig_x, orig_y, xx, yy)
nearestWidget = v.widgetID
end
end
end
if nearestWidget ~= 0 then
self.widget.selected = nearestWidget
end
end
function GridBox:moveLine(direction)
local orig_x, orig_y = self:getSlotCenter(self.widget.selected)
local distance = self.h -- on met directement à la distance max possible le système
local nearastWidget = 0
for i,v in ipairs(self.slots) do
local xx, yy = self:getSlotCenter(i)
-- On commence par vérifier si le slot est bien positionné par rapport au
-- widget de base
if utils.math.sign(yy - orig_y) == direction then
if utils.math.pointDistance(orig_x, orig_y, xx, yy) < distance then
distance = utils.math.pointDistance(orig_x, orig_y, xx, yy)
nearestWidget = v.widgetID
end
end
end
if nearestWidget ~= 0 then
self.widget.selected = nearestWidget
end
end
function GridBox:mousemoved(x, y)
local widgetID = self:getWidgetAtPoint(x, y)
if widgetID ~= nil then
self.widget.selected = widgetID
self:getFocus()
end
if self.widget.selected < 1 then
self.widget.selected = 1
end
if self.widget.selected > #self.widget.list then
self.widget.selected = #self.widget.list
end
end
function GridBox:mousepressed(x, y, button, isTouch)
local widgetID = self:getWidgetAtPoint(x, y)
if widgetID ~= nil then
self.widget.selected = widgetID
self:getFocus()
if #self.widget.list > 0 and self.widget.selected > 1 and self.widget.selected <= #self.widget.list then
self.widget.list[self.widget.selected]:action()
end
end
end
function GridBox:draw()
for i,v in ipairs(self.slots) do
if self:haveWidget(i) then
local widgetx = self.x + (v.x * self.widget.w)
local widgety = self.y + (v.y * self.widget.h)
if self.widget.selected == v.widgetID and self:haveFocus() == true then
self.widget.list[v.widgetID]:drawSelected(widgetx, widgety)
else
self.widget.list[v.widgetID]:draw(widgetx, widgety)
end
end
end
end
function GridBox:drawCursor()
self:updateView()
if (self.widget.selected >= 1 and self.widget.selected <= #self.widget.list) then
local slot = self:getWidgetSlot(self.widget.selected)
local w, h = self:getWidgetSize(slot)
local x = self.slots[slot].x * self.widget.w
local y = self.slots[slot].y * self.widget.h
menuutils.drawCursor(self.x + x, self.y + y, w, h)
end
end
return GridBox

111
modules/menusystem/init.lua Normal file
View file

@ -0,0 +1,111 @@
local MenuSystem = Object:extend()
local cwd = (...):gsub('%.init$', '') .. "."
MenuSystem.Parent = require(cwd .. "parent")
MenuSystem.ListBox = require(cwd .. "listbox")
MenuSystem.FlowBox = require(cwd .. "flowbox")
MenuSystem.Grid = require(cwd .. "grid")
MenuSystem.TextMenu = require(cwd .. "textmenu")
MenuSystem.Widget = require(cwd .. "widgets")
--local VirtualPad = require "modules.virtualpad"
function MenuSystem:new()
self.menus = {}
self.focusedMenu = ""
end
function MenuSystem:reset()
self.menus = {}
end
function MenuSystem:addMenu(name, menu)
self.menus[name] = menu
end
function MenuSystem:update(dt)
self:removeDestroyedMenus()
for k,v in pairs(self.menus) do
v:update(dt)
v:updateWidgets(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 k,v in pairs(self.keys) do
if self.keys[k].isPressed then
self.menus[self.focusedMenu]:keyreleased(k)
end
end
end
end
end
function MenuSystem:setAllMenuVisibility(visibility)
for k,v in pairs(self.menus) do
v.isVisible = visibility
end
end
function MenuSystem:setAllMenuActivity(activity)
for k,v in pairs(self.menus) do
v.isActive = activity
end
end
function MenuSystem:removeDestroyedMenus()
-- On retire les entitées marquées comme supprimées
for k,v in pairs(self.menus) do
if (v.isDestroyed == true) then
self.menus[k] = nil
end
end
end
function MenuSystem:keyreleased(key, code)
-- TODO:depreciated function
end
function MenuSystem:mousemoved(x, y, dx, dy)
for k,v in pairs(self.menus) do
if v.isActive then
if (x > v.x) and (x < v.x + v.w) and (y > v.y) and (y < v.y + v.h) then
v:mousemoved(x - v.x, y - v.y)
break;
end
end
end
end
function MenuSystem:mousepressed( x, y, button, istouch )
for k,v in pairs(self.menus) do
if v.isActive then
if (x > v.x) and (x < v.x + v.w) and (y > v.y) and (y < v.y + v.h) then
v:mousepressed(x - v.x, y - v.y, button, istouch )
break;
end
end
end
end
function MenuSystem:draw(dt) -- On dessine les entitées
for k,v in pairs(self.menus) do
if (v.isVisible) then
v:draw(dt)
end
end
if self.menus[self.focusedMenu] ~= nil then
if (self.menus[self.focusedMenu].isVisible) then
self.menus[self.focusedMenu]:drawCursor()
end
end
end
return MenuSystem

View file

@ -0,0 +1,110 @@
local cwd = (...):gsub('%.listbox$', '') .. "."
local Menu = require(cwd .. "parent")
local menuutils = require(cwd .. "widgets.utils")
local ListBox = Menu:extend()
function ListBox:new(menusystem, name, x, y, w, h, slotNumber)
self.view = {}
self.view.slotNumber = slotNumber
self.view.firstSlot = 1
ListBox.super.new(self, menusystem, name, x, y, w, h)
self.h = slotNumber * self.widget.h -- On fait en sorte que la hauteur
-- soit un multiple du nombre de slot et de leur hauteur
end
function ListBox:updateWidgetSize()
self.widget.h = math.floor( self.h / self.view.slotNumber )
self.widget.w = self.w
end
function ListBox:update(dt)
self:updateView()
end
function ListBox:updateView()
if self.widget.selected < self.view.firstSlot then
self.view.firstSlot = self.widget.selected
end
if self.widget.selected > self.view.firstSlot + self.view.slotNumber - 1 then
self.view.firstSlot = self.widget.selected - self.view.slotNumber + 1
end
if self.view.firstSlot < 1 then
self.view.firstSlot = 1
end
end
function ListBox:keyreleased(key, code)
if key == 'up' then
self:moveCursor(self.widget.selected - 1)
end
if key == 'down' then
self:moveCursor(self.widget.selected + 1)
end
if key == "A" then
if (self.widget.selected >= 1 and self.widget.selected <= #self.widget.list) then
self.widget.list[self.widget.selected]:action()
end
end
if key == "B" then
if (self.widget.cancel >= 1 and self.widget.cancel <= #self.widget.list) then
self.widget.list[self.widget.cancel]:action()
end
end
end
function ListBox:mousemoved(x, y)
local widget_selected = self.view.firstSlot + math.floor(y / self.widget.h)
if widget_selected >= 1 and widget_selected <= #self.widget.list then
self.widget.selected = widget_selected
self:getFocus()
end
end
function ListBox:mousepressed(x, y, button, isTouch)
local widget_selected = self.view.firstSlot + math.floor(y / self.widget.h)
if widget_selected >= 1 and widget_selected <= #self.widget.list then
self.widget.selected = widget_selected
self:getFocus()
if #self.widget.list > 0 then
self.widget.list[self.widget.selected]:action()
end
end
end
function ListBox:draw()
self:updateView()
local widgety = self.y
for i,v in ipairs(self.widget.list) do
if (i >= self.view.firstSlot) and (i < self.view.firstSlot + self.view.slotNumber) then
v:draw(self.x, widgety, self.w, self.widget.h)
if self.widget.selected == i and self:haveFocus() == true then
v:drawSelected(self.x, widgety, self.w, self.widget.h)
else
v:draw(self.x, widgety, self.w, self.widget.h)
end
widgety = widgety + self.widget.h
end
end
end
function ListBox:drawCursor()
self:updateView()
if (self.widget.selected >= 1 and self.widget.selected <= #self.widget.list) then
local w, h = self:getWidgetSize()
local y = (self.widget.selected - self.view.firstSlot) * h
menuutils.drawCursor(self.x,self.y + y, w, h)
end
end
return ListBox

View file

@ -0,0 +1,179 @@
local Menu = Object:extend()
function Menu:new(menusystem, name, x, y, w, h)
self.menusystem = menusystem
self.name = name
self.x = x
self.y = y
self.w = w
self.h = h
self.widget = {}
self.widget.list = {}
self.widget.selected = 0
self.widget.selectedPrevious = 0
self.widget.cancel = 0
self:updateWidgetSize()
self.isDestroyed = false
self.isVisible = true
self.isActive = true
self.sound = {}
self.sound.asset = nil
self.sound.active = false
self:register()
end
function Menu:getFocus()
self.menusystem.focusedMenu = self.name
end
function Menu:haveFocus()
return (self.menusystem.focusedMenu == self.name)
end
function Menu:register()
self.menusystem:addMenu(self.name, self)
end
function Menu:setCancelWidget(id)
self.widget.cancel = #self.widget.list
end
function Menu:updateWidgetSize()
self.widget.h = 0
self.widget.w = 0
end
function Menu:getWidgetSize(id)
return self.widget.w, self.widget.h
end
function Menu:cancelAction()
if (self.widget.cancel ~= 0) then
self.widget.list[self.widget.cancel]:action()
end
end
function Menu:update(dt)
-- Cette fonction ne contient rien par défaut
end
function Menu:clear()
self.widget.list = {}
self.widget.cancel = 0
end
function Menu:resize(x,y,w,h)
self.x = x
self.y = y
self.w = w
self.h = h
self:updateWidgetSize()
end
function Menu:destroy()
self.destroyed = true
end
function Menu:draw()
-- nothing here
end
function Menu:drawCursor()
-- nothing here
end
function Menu:drawCanvas()
end
function Menu:keyreleased(key)
-- Cette fonction ne contient rien par défaut
end
function Menu:mousemoved(x, y)
-- Cette fonction ne contient rien par défaut
end
function Menu:mousepressed( x, y, button, istouch )
-- Cette fonction ne contient rien par défaut
end
function Menu:addWidget(newwidget)
if #self.widget.list == 0 then
self.widget.selected = 1
end
table.insert(self.widget.list, newwidget)
self:updateWidgetsID()
end
function Menu:updateWidgets(dt)
self:removeDestroyedWidgets()
for i,v in ipairs(self.widget.list) do
v.id = i
v:update(dt)
end
end
function Menu:updateWidgetsID()
for i,v in ipairs(self.widget.list) do
v.id = i
end
end
function Menu:removeDestroyedWidgets() -- On retire les widgets marquées comme supprimées
for i,v in ipairs(self.widget.list) do
if (v.destroyed == true) then
table.remove(self.widget.list, i)
end
end
end
function Menu:setCursor(cursorid)
self.widget.selected = cursorid --math.max(1, math.min(cursorid, #self.widget.list))
end
function Menu:moveCursor(new_selected)
self:playSelectSound()
if new_selected < 1 then
self.widget.selected = #self.widget.list + new_selected
else
if new_selected > #self.widget.list then
self.widget.selected = new_selected - #self.widget.list
else
self.widget.selected = new_selected
end
end
end
function Menu:setSound(soundasset)
self.sound.active = true
self.sound.asset = soundasset
end
function Menu:playSelectSound()
if self.sound.active == true then
love.audio.stop( self.sound.asset )
self.sound.asset:setVolume(core.options.data.audio.sfx / 100)
love.audio.play( self.sound.asset )
end
end
function Menu:resetView()
-- ne sert à rien ici, c'est juste pour éviter des crash
end
function Menu:updateView()
-- ne sert à rien ici, c'est juste pour éviter des crash
end
function Menu:moveView()
-- ne sert à rien ici, c'est juste pour éviter des crash
end
return Menu

View file

@ -0,0 +1,221 @@
local cwd = (...):gsub('%.textmenu$', '') .. "."
local Menu = require(cwd .. "parent")
local TextMenu = Menu:extend()
function TextMenu:new(menusystem, name, x, y, font, slots)
self.slots = slots
TextMenu.super.new(self, menusystem, name, x, y, 0, 0)
self.ox = x
self.oy = y
self.font = font
self.align = "left"
self.begin = 1
self:getBoundingBox()
end
function TextMenu:getBoundingBox()
self:setWidthAuto()
self.widget.h = self.font:getHeight()
self.h = self.widget.h * self.slots
if self.align == "right" then
self.x = self.ox - self.w
elseif self.align == "center" then
self.x = self.ox - self.w / 2
else
self.x = self.ox
end
self.y = self.oy
end
function TextMenu:centerText()
self:setAlign("center")
end
function TextMenu:setAlign(align)
self.align = align
self.font:setAlign("center")
end
function TextMenu:update(dt)
self:getBoundingBox()
if self.widget.selected ~= 0 then
if self.widget.selected < self.begin then
self.begin = self.widget.selected
end
if self.widget.selected > self.begin + self.slots - 1 then
self.begin = self.widget.selected - self.slots + 1
end
end
if self.begin < 1 then
self.begin = 1
end
end
function TextMenu:setWidthAuto()
local width = self.w
for i,v in ipairs(self.widget.list) do
local stringWidth = self.font:getWidth(v.beginlabel .. v.label .. v.endlabel)
width = math.max(stringWidth, width)
end
if width ~= self.w then
self.canvas.needRedraw = true
end
self.w = width
end
function TextMenu:getWidth()
self:setWidthAuto()
return self.w
end
function TextMenu:getHeight()
return self.h
end
function TextMenu:keyreleased(key, code)
if key == 'up' then
self:moveCursor(self.widget.selected - 1)
end
if key == 'down' then
self:moveCursor(self.widget.selected + 1)
end
if key == "A" then
if (self.widget.selected > 0) and (self.widget.selected <= #self.widget.list) then
self.widget.list[self.widget.selected]:action()
end
end
if key == "B" then
self:cancelAction()
end
end
function TextMenu:mousemoved(x, y)
local selectedPrevous = self.widget.selected
self.widget.selected = self.begin + math.floor(y / self.widget.h)
if self.widget.selected < 1 then
self.widget.selected = 1
end
if self.widget.selected > #self.widget.list then
self.widget.selected = #self.widget.list
end
if self.widget.selected ~= selectedPrevious then
self.canvas.needRedraw = true
end
end
function TextMenu:mousepressed(x, y, button, isTouch)
self.widget.selected = self.begin + math.floor(y / self.widget.h)
if self.widget.selected < 1 then
self.widget.selected = 1
end
if self.widget.selected > #self.widget.list then
self.widget.selected = #self.widget.list
end
if #self.widget.list > 0 then
self.widget.list[self.widget.selected]:action()
end
if self.widget.selected ~= selectedPrevious then
self.canvas.needRedraw = true
end
end
function TextMenu:drawCanvas()
print("redraw menu")
self.canvas.texture = love.graphics.newCanvas(self.w, self.h)
love.graphics.setCanvas( self.canvas.texture )
local ox, x
local widgety = 0
local ox = self.w / 2
local x = 0
self.font:set()
for i, v in ipairs(self.widget.list) do
if (i >= self.begin) and (i < self.begin + self.slots) then
self:drawWidget(i, widgety)
widgety = widgety + self.widget.h
end
end
utils.draw.resetColor()
love.graphics.setCanvas( )
end
function TextMenu:drawWidget(widgetID, y)
local widget = self.widget.list[widgetID]
print(widget)
if widget.canvas.needRedraw == true then
self:drawWidgetCanvas(widget)
widget.canvas.needRedraw = false
end
if self.widget.selected == widgetID and self.focus == true then
love.graphics.setColor(1, 1, 0, 1)
else
love.graphics.setColor(1, 1, 1, 1)
end
love.graphics.draw(widget.canvas.texture, 0, y)
end
function TextMenu:drawWidgetCanvas(widget)
widget.canvas.texture = love.graphics.newCanvas(self.w, self.widget.h)
love.graphics.setCanvas( widget.canvas.texture )
self.font:draw(widget.label, math.floor(self.w / 2), 0, -1, self.align)
self.font:draw(widget.beginlabel, math.floor(0), 0, -1, "left")
self.font:draw(widget.endlabel, math.floor(self.w), 0, -1, "right")
love.graphics.setCanvas( self.canvas.texture )
end
function TextMenu:resetView()
self.begin = 1
self.canvas.needRedraw = true
end
function Menu:moveView(begin, absolute)
--local absolute = absolute or true
self.widget.selected = 0
if (absolute) then
self.begin = begin
else
self.begin = self.begin + begin
end
-- ne sert à rien ici, c'est juste pour éviter des crash
self.canvas.needRedraw = true
end
function Menu:getView()
return self.begin
end
function Menu:isViewAtBeggining()
return (self.begin <= 1)
end
function Menu:isViewAtEnd()
return ((self.begin + self.slots) > (#self.widget.list))
end
return TextMenu

View file

@ -0,0 +1,98 @@
local Widget = {}
BaseWidget = Object:extend()
TextWidget = BaseWidget:extend()
function BaseWidget:new(menu)
self.menu = menu
self.destroyed = false
self.selectable = false
self.selection_margin = 0
self.margin = 2
self:register()
self.canvas = {}
self.canvas.texture = nil
self.canvas.needRedraw = true
end
function BaseWidget:register()
self.menu:addWidget(self)
end
function BaseWidget:redrawCanvas()
self.width, self.height = self.menu:getWidgetSize(self.id)
self.canvas.texture = love.graphics.newCanvas(self.width, self.height)
love.graphics.setCanvas( self.canvas.texture )
self:drawCanvas()
self.canvas.needRedraw = false
love.graphics.setCanvas( )
end
function BaseWidget:drawCanvas()
self.r = love.math.random(128)/256
self.g = love.math.random(128)/256
self.b = love.math.random(128)/256
love.graphics.setColor(self.r, self.g, self.b, 70)
love.graphics.rectangle("fill", 0, 0, self.width, self.height)
love.graphics.setColor(self.r, self.g, self.b)
love.graphics.rectangle("line", 0, 0, self.width, self.height)
utils.graphics.resetColor()
end
function BaseWidget:selectAction()
-- Do nothing
end
function BaseWidget:draw(x, y)
if self.canvas.texture ~= nil then
utils.graphics.resetColor()
love.graphics.draw(self.canvas.texture, x, y)
end
end
function BaseWidget:drawSelected(x,y,w,h)
self:draw(x, y, w, h)
end
function BaseWidget:update(dt)
if (self.canvas.needRedraw) then
self:redrawCanvas()
end
-- N/A
end
function BaseWidget:action()
--self:destroy()
end
function BaseWidget:destroy()
self.destroyed = true
end
-- Simple text widget
function TextWidget:new(menu, font, label)
TextWidget.super.new(self, menu)
self.font = font
self.label = label
end
function TextWidget:drawCanvas()
local w, h
w = math.floor(self.width / 2)
h = math.floor(self.height / 2) - (self.font:getHeight() / 2)
self.font:draw(self.label, w, h, -1, "center")
end
Widget.Base = BaseWidget
Widget.Text = TextWidget
return Widget

View file

@ -0,0 +1,34 @@
local menuUtils = {}
function menuUtils.drawCursor(x, y, w, h)
love.graphics.setColor(0,0,0)
love.graphics.rectangle("fill", x, y, 4, 8)
love.graphics.rectangle("fill", x, y, 8, 4)
love.graphics.rectangle("fill", x + w, y, -4, 8)
love.graphics.rectangle("fill", x + w, y, -8, 4)
love.graphics.rectangle("fill", x, y + h, 4, -8)
love.graphics.rectangle("fill", x, y + h, 8, -4)
love.graphics.rectangle("fill", x + w, y + h, -4, -8)
love.graphics.rectangle("fill", x + w, y + h, -8, -4)
love.graphics.setColor(255,255,255)
love.graphics.rectangle("fill", x + 1, y + 1, 2, 6)
love.graphics.rectangle("fill", x + 1, y + 1, 6, 2)
love.graphics.rectangle("fill", x + w - 1, y + 1, -2, 6)
love.graphics.rectangle("fill", x + w - 1, y + 1, -6, 2)
love.graphics.rectangle("fill", x + 1, y + h - 1, 2, -6)
love.graphics.rectangle("fill", x + 1, y + h - 1, 6, -2)
love.graphics.rectangle("fill", x + w - 1, y + h - 1, -2, -6)
love.graphics.rectangle("fill", x + w - 1, y + h - 1, -6, -2)
end
return menuUtils

67
modules/scenes.lua Normal file
View file

@ -0,0 +1,67 @@
-- scenes.lua :: the scene object, that aim to give a better control to the engine
-- to the different scene, without having to call too much boilerplate
--[[
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 Scene = Object:extend()
local Assets = require "core.modules.assets"
local MenuSystem = require "core.modules.menusystem"
function Scene:new()
self.mouse = {}
self.mouse.x, self.mouse.y = core.screen:getMousePosition()
self.assets = Assets()
self.menusystem = MenuSystem()
self.keys = core.input:getKeyList()
end
function Scene:register()
core.scenemanager.currentScene = self
end
function Scene:update(dt)
-- Empty function, is just here to avoid crash
end
function Scene:mousemoved(x, y, dx, dy)
-- Empty function, is just here to avoid crash
end
function Scene:mousepressed( x, y, button, istouch )
-- Empty function, is just here to avoid crash
end
function Scene:draw()
end
function Scene:clear()
end
function Scene:flushKeys()
core.input:flushKeys()
self.keys = core.input.keys
end
return Scene

96
options.lua Normal file
View file

@ -0,0 +1,96 @@
-- core/options.lua :: The options loading/saving system. Is used by the other
-- modules to save their settings.
--[[
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 OptionsManager = Object:extend()
local binser = require "libs.binser"
function OptionsManager:new()
-- We begin by creating an empty data table before reading the data.
self.data = {}
self:read()
end
function OptionsManager:reset()
-- Reset the option to the game defaults.
self.data.video = {}
self.data.video.crtfilter = false
self.data.video.resolution = 1
self.data.video.border = true
self.data.video.vsync = false
self.data.video.fullscreen = false
-- We load the default files
self.data.input = require "datas.inputs"
-- TODO: have a way to auto-load a language according to the OS ?
self.data.language = "en"
self.data.audio = {}
self.data.audio.music = 100
self.data.audio.sfx = 100
end
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:write()
local data = self:getData()
filepath = self:getFile(true)
binser.writeFile(filepath, data)
end
function OptionsManager:read()
filepath = self:getFile(true)
if utils.filesystem.exists("options.data") then
local loadedDatas = binser.readFile(filepath)
print("data file found, loading it")
self:setData(loadedDatas[1])
else
self:reset()
print("no data file found, reseting data")
end
end
function OptionsManager:getData(data)
return self.data
end
function OptionsManager:setData(data)
self.data = data
end
return OptionsManager

69
scenemanager.lua Normal file
View file

@ -0,0 +1,69 @@
-- scene.lua :: a basic scene management system, that work by sending the different
-- core functions to the scene, normally without the scene itself having to manage
-- them.
--[[
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 SceneManager = Object:extend()
function SceneManager:new(controller)
self.controller = controller
self.currentScene = nil
end
function SceneManager:update(dt)
if (self.currentScene ~= nil) then
local keys = self.controller.input.keys
self.currentScene.keys = keys
self.currentScene.menusystem.keys = keys
self.currentScene.assets:update(dt)
self.currentScene.menusystem:update(dt)
self.currentScene:update(dt)
end
end
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
function SceneManager:mousepressed( x, y, button, istouch )
self.currentScene:mousepressed( x, y, button, istouch )
self.currentScene.menusystem:mousepressed( x, y, button, istouch )
end
function SceneManager:clearScene()
self.currentScene = nil
end
function SceneManager:draw()
self.controller.screen:apply()
if (self.currentScene ~= nil) then
self.currentScene:draw(dt)
self.currentScene.menusystem:draw()
end
self.controller.screen:cease()
end
return SceneManager

74
screen.lua Normal file
View file

@ -0,0 +1,74 @@
-- core/screen.lua :: Basic screen manager. Use CScreen as a backend, and works
-- as an abstraction layer around CScreen.
--[[
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 ScreenManager = Object:extend()
local CScreen = require "libs.cscreen"
function ScreenManager:new(controller)
self.controller = controller
self.data = self.controller.options.data.video
self.width, self.height = love.graphics.getDimensions()
self:applySettings()
CScreen.init(self.width, self.height, true)
CScreen.setColor(0, 0, 0, 1)
love.graphics.setDefaultFilter( "nearest", "nearest", 1 )
end
function ScreenManager:applySettings()
self.data = self.controller.options.data.video
local flags = {}
flags.vsync = self.data.vsync
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 )
local width, height = love.window.getMode()
CScreen.update(width, height)
end
function ScreenManager:project(x, y)
return CScreen.project(x, y)
end
function ScreenManager:getMousePosition()
return CScreen.project(love.mouse.getX(), love.mouse.getY())
end
function ScreenManager:getDimensions()
return self.width, self.height
end
function ScreenManager:apply()
CScreen.apply()
end
function ScreenManager:cease()
CScreen.cease()
end
return ScreenManager