diff --git a/assets/imgs/floppy.png b/assets/imgs/floppy.png new file mode 100644 index 0000000..d3974e5 Binary files /dev/null and b/assets/imgs/floppy.png differ diff --git a/licenses/OFL.TXT b/licenses/OFL.TXT new file mode 100644 index 0000000..40bd8a6 --- /dev/null +++ b/licenses/OFL.TXT @@ -0,0 +1,97 @@ +Copyright (c) , (), +with Reserved Font Name . +Copyright (c) , (), +with Reserved Font Name . +Copyright (c) , (). + +This Font Software is licensed under the SIL Open Font License, Version 1.1. +This license is copied below, and is also available with a FAQ at: +https://openfontlicense.org + + +----------------------------------------------------------- +SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 +----------------------------------------------------------- + +PREAMBLE +The goals of the Open Font License (OFL) are to stimulate worldwide +development of collaborative font projects, to support the font creation +efforts of academic and linguistic communities, and to provide a free and +open framework in which fonts may be shared and improved in partnership +with others. + +The OFL allows the licensed fonts to be used, studied, modified and +redistributed freely as long as they are not sold by themselves. The +fonts, including any derivative works, can be bundled, embedded, +redistributed and/or sold with any software provided that any reserved +names are not used by derivative works. The fonts and derivatives, +however, cannot be released under any other type of license. The +requirement for fonts to remain under this license does not apply +to any document created using the fonts or their derivatives. + +DEFINITIONS +"Font Software" refers to the set of files released by the Copyright +Holder(s) under this license and clearly marked as such. This may +include source files, build scripts and documentation. + +"Reserved Font Name" refers to any names specified as such after the +copyright statement(s). + +"Original Version" refers to the collection of Font Software components as +distributed by the Copyright Holder(s). + +"Modified Version" refers to any derivative made by adding to, deleting, +or substituting -- in part or in whole -- any of the components of the +Original Version, by changing formats or by porting the Font Software to a +new environment. + +"Author" refers to any designer, engineer, programmer, technical +writer or other person who contributed to the Font Software. + +PERMISSION & CONDITIONS +Permission is hereby granted, free of charge, to any person obtaining +a copy of the Font Software, to use, study, copy, merge, embed, modify, +redistribute, and sell modified and unmodified copies of the Font +Software, subject to the following conditions: + +1) Neither the Font Software nor any of its individual components, +in Original or Modified Versions, may be sold by itself. + +2) Original or Modified Versions of the Font Software may be bundled, +redistributed and/or sold with any software, provided that each copy +contains the above copyright notice and this license. These can be +included either as stand-alone text files, human-readable headers or +in the appropriate machine-readable metadata fields within text or +binary files as long as those fields can be easily viewed by the user. + +3) No Modified Version of the Font Software may use the Reserved Font +Name(s) unless explicit written permission is granted by the corresponding +Copyright Holder. This restriction only applies to the primary font name as +presented to the users. + +4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font +Software shall not be used to promote, endorse or advertise any +Modified Version, except to acknowledge the contribution(s) of the +Copyright Holder(s) and the Author(s) or with their explicit written +permission. + +5) The Font Software, modified or unmodified, in part or in whole, +must be distributed entirely under this license, and must not be +distributed under any other license. The requirement for fonts to +remain under this license does not apply to any document created +using the Font Software. + +TERMINATION +This license becomes null and void if any of the above conditions are +not met. + +DISCLAIMER +THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT +OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE +COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM +OTHER DEALINGS IN THE FONT SOFTWARE. diff --git a/src/graphics/drawable.lua b/src/graphics/drawable.lua index a93f4ab..71f4c02 100644 --- a/src/graphics/drawable.lua +++ b/src/graphics/drawable.lua @@ -16,7 +16,8 @@ local Drawable = make_class(Asset) -- Class methods ------------------------------------------------------------------------------ -function Drawable:_init() +function Drawable:_init(file_name) + Asset._init(self, file_name) end diff --git a/src/graphics/sprite.lua b/src/graphics/sprite.lua index cedc6b7..914eda8 100644 --- a/src/graphics/sprite.lua +++ b/src/graphics/sprite.lua @@ -17,15 +17,15 @@ local Sprite = make_class(Drawable) -- Class methods ------------------------------------------------------------------------------ -function Sprite:_init(sprite_name, x, y) - self.sprite_name = string.format('assets/%s', sprite_name) +function Sprite:_init(file_name, x, y) + Drawable._init(self, file_name) self.x = (x ~= nil and x) or 0 self.y = (y ~= nil and y) or 0 end function Sprite:load() - self.sprite = love.graphics.newImage(self.sprite_name) + self.sprite = love.graphics.newImage(self.file_name) end diff --git a/src/gstates/gstate.lua b/src/gstates/gstate.lua index 12cdaa1..ca2abf3 100644 --- a/src/gstates/gstate.lua +++ b/src/gstates/gstate.lua @@ -3,8 +3,10 @@ ------------------------------------------------------------------------------ local make_class = require 'src.utils.classes' +local assets = require 'src.utils.asstmngr' local Drawable = require 'src.graphics.drawable' + ------------------------------------------------------------------------------ -- Class definitions ------------------------------------------------------------------------------ @@ -18,8 +20,8 @@ local GameState = make_class(Drawable) function GameState:_init(name, index) Drawable._init(self) - self.name = name - self.index = index + self.name = name + self.index = index end @@ -28,6 +30,15 @@ function GameState:update(_) end +function GameState:load() +end + + +function GameState:unload() + assets:unload(self.name) +end + + ------------------------------------------------------------------------------ -- Module return ------------------------------------------------------------------------------ diff --git a/src/gstates/menu.lua b/src/gstates/menu.lua index e339e66..df90fb0 100644 --- a/src/gstates/menu.lua +++ b/src/gstates/menu.lua @@ -3,6 +3,7 @@ ------------------------------------------------------------------------------ local love = require 'love' +local assets = require 'src.utils.asstmngr' local make_class = require 'src.utils.classes' local GameState = require 'src.gstates.gstate' local Fader = require 'src.graphics.fader' @@ -36,40 +37,37 @@ function MainMenu:_init(name, index) -- Create sound effects. self.bgm = SoundEffect('bgm/eskisky.wav') -end - -function MainMenu:load() - -- Load sprites. - self.background:load() - self.cursor:load() - - -- Load sound effects and start playing the background music - self.bgm:load() - self.bgm:play() + -- Register all assets. + assets:register(self.name, self.background) + assets:register(self.name, self.cursor) + assets:register(self.name, self.bgm) end function MainMenu:update(dt) - -- Update the fader. - self.fade:update(dt) + if assets:done(self.name) then + if not self.bgm:isPlaying() then self.bgm:play() end - -- Move on to the next game state if the user skipped the intro or all stages are complete. - if not self.skip then return self.index else return -1 end + -- Update the fader. + self.fade:update(dt) + + -- Move on to the next game state if the user skipped the intro or all stages are complete. + if not self.skip then return self.index else return -1 end + else + assets:update(self.name) + end end function MainMenu:draw() - self.background:draw() - self.cursor:draw() - self.fade:draw() -end - - -function MainMenu:unload() - self.background:unload() - self.cursor:unload() - self.bgm:unload() + if assets:done(self.name) then + self.background:draw() + self.cursor:draw() + self.fade:draw() + else + assets:draw() + end end diff --git a/src/sound/sfx.lua b/src/sound/sfx.lua index a9536c4..b1a7421 100644 --- a/src/sound/sfx.lua +++ b/src/sound/sfx.lua @@ -11,7 +11,7 @@ local Asset = require 'src.utils.asset' ------------------------------------------------------------------------------ -- SoundEffect is a simple wrapper around Löve's Source class to allow for --- easy loading/unloading and automatically hecking if a sound effect is valid +-- easy loading/unloading and automatically checking if a sound effect is valid -- before using it. local SoundEffect = make_class(Asset) @@ -21,7 +21,7 @@ local SoundEffect = make_class(Asset) ------------------------------------------------------------------------------ function SoundEffect:_init(file_name) - self.file_name = string.format('assets/%s', file_name) + Asset._init(self, file_name) end diff --git a/src/ui/font.lua b/src/ui/font.lua new file mode 100644 index 0000000..bc2d95a --- /dev/null +++ b/src/ui/font.lua @@ -0,0 +1,53 @@ +------------------------------------------------------------------------------ +-- Imports +------------------------------------------------------------------------------ + +local love = require 'love' +local make_class = require 'src.utils.classes' +local Asset = require 'src.utils.asset' + +------------------------------------------------------------------------------ +-- Class definitions +------------------------------------------------------------------------------ + +-- Font is a simple wrapper around Löve's own Font class to allow for +-- easy loading/unloading and automatically checking if it's is valid +-- before using it. +local Font = make_class(Asset) + + +------------------------------------------------------------------------------ +-- Class methods +------------------------------------------------------------------------------ + +function Font:_init(file_name, size) + self.file_name = string.format('assets/%s', file_name) + self.size = (size ~= nil and size) or 20 +end + + +function Font:load() + self.f = love.graphics.newFont(self.file_name, self.size) +end + + +function Font:unload() + self.f = nil +end + + +function Font:set() + if self.f ~= nil then love.graphics.setFont(self.f) end +end + + +function Font:unset() + love.graphics.setFont() +end + + +------------------------------------------------------------------------------ +-- Module return +------------------------------------------------------------------------------ + +return Font diff --git a/src/utils/asset.lua b/src/utils/asset.lua index 324c08f..cfa74c2 100644 --- a/src/utils/asset.lua +++ b/src/utils/asset.lua @@ -16,15 +16,18 @@ local Asset = make_class() -- Class methods ------------------------------------------------------------------------------ -function Asset:_init() +function Asset:_init(file_name) + self.file_name = string.format('assets/%s', file_name) end function Asset:load() + error 'Attempted to load unimplemented asset.' end function Asset:unload() + error 'Attempted to unload unimplemented asset.' end diff --git a/src/utils/asstmngr.lua b/src/utils/asstmngr.lua new file mode 100644 index 0000000..b53884a --- /dev/null +++ b/src/utils/asstmngr.lua @@ -0,0 +1,130 @@ +------------------------------------------------------------------------------ +-- Imports +------------------------------------------------------------------------------ + +local love = require 'love' +local make_class = require 'src.utils.classes' +local Drawable = require 'src.graphics.drawable' +local Sprite = require 'src.graphics.sprite' +local Font = require 'src.ui.font' + +------------------------------------------------------------------------------ +-- Class definitions +------------------------------------------------------------------------------ + +local AssetManager = make_class(Drawable) +local Asset = require 'src.utils.asset' + + +------------------------------------------------------------------------------ +-- Helper functions +------------------------------------------------------------------------------ + +local function _load(manager, owner) + if manager.assets[owner] ~= nil then + for k, _ in pairs(manager.assets[owner]) do + if k.is_a ~= nil and k.is_a[Asset] then + k:load() + end + coroutine.yield(false) + end + end + + return true +end + + +------------------------------------------------------------------------------ +-- Class methods +------------------------------------------------------------------------------ + +function AssetManager:_init() + Drawable._init(self) + self.assets = {} + self.bckg = Sprite('imgs/floppy.png') + self.font = Font('fonts/Concrete.ttf', 40) + self.co = nil + + self.bckg:load() + self.font:load() +end + + +function AssetManager:unload(owner) + -- If the owner is known... + if self.assets[owner] ~= nil then + -- Iterate over it's asset set and unload everything. + for k, _ in pairs(self.assets[owner]) do + if k.is_a ~= nil and k.is_a[Asset] then + k:unload() + end + end + end +end + + +function AssetManager:update(owner) + if self.assets[owner] ~= nil then + if self.co == nil then + self.co = coroutine.create(_load) + end + + local errorfree, retval = coroutine.resume(self.co, self, owner) + + if errorfree then + self.assets[owner].done = retval + else + error(retval) + end + end +end + + +function AssetManager:draw() + self.bckg:draw() + + love.graphics.setColor(195, 147, 123) + self.font:set() + love.graphics.print('Loading...', 5, 150) + self.font:unset() + love.graphics.setColor() +end + + +function AssetManager:register(owner, asset) + -- If the owner is new, then create an asset set for it. + if self.assets[owner] == nil then + self.assets[owner] = { + done = false, + } + end + + -- Store the asset in the set. + self.assets[owner][asset] = true +end + + +function AssetManager:remove(owner, asset) + -- If the owner is new, then create an asset set for it. + if self.assets[owner] ~= nil then + -- Unload the asset just in case. + if self.assets[owner][asset] ~= nil then + self.assets[owner][asset]:unload() + end + + -- Then remove it from the set. + self.assets[owner][asset] = nil + end +end + + +function AssetManager:done(owner) + return self.assets[owner] ~= nil and self.assets[owner].done +end + + +------------------------------------------------------------------------------ +-- Module return +------------------------------------------------------------------------------ + +return AssetManager() diff --git a/src/utils/classes.lua b/src/utils/classes.lua index 0923b10..760e2c6 100644 --- a/src/utils/classes.lua +++ b/src/utils/classes.lua @@ -20,7 +20,9 @@ local function make_class(BaseClass) cls.__index, cls.is_a = cls, {[cls] = true} if BaseClass ~= nil then - cls.is_a[BaseClass] = true + for k, _ in pairs(BaseClass.is_a) do + cls.is_a[k] = true + end end -- the class's __call metamethod