So I set about making one for LOVE, and below is the file itself, I've also made a little demo .love package to show what it's capable of.
What this lib allows you to do is make multiple tables (scenes) that each have their own bg (rgb or img) and you can make each have a set of update functions, and a set of draw functions which get called in the respective love functions in the main.lua (or wherever else you call them from). You can also set the active scene from anywhere you like (so it would be easy to implement game states) and you can replace the update/draw functions of individual scenes if you want
So I guess simply it sort of lets you make little game scripts in one.
Code: Select all
-- An attempt to implement a scenes system for LOVE 2D,
-- Made by mattyhex {mattyhex@mattyhex.net}
-- Free for all uses and free to edit/redistribute on grounds that my name +
-- this notice remains intact and unmodified.
-- I accept no liability for the fullness or reliabilty of this code...yaddayadda.
-- First the global scenes table, for access to all scenes
scenes = {}
scenes.__index = scenes
-- Next the setup for individual scenes
local scene = {}
scene.__index = scene
-- Make a new scene
-- @param name: string to indentify the scene in the scenes table
-- @param bg: false for no background, else rgb table or img
function newScene(name, bg, update, draw)
local s = {}
if bg then -- check for a background
if type(bg) == 'userdata' then -- determine the type
s.bg = bg -- set the background value
elseif type(bg) == 'table' then
if #bg < 4 then -- pad the table for 0.8.0
for i=1,4-#bg do
table.insert(bg, 0)
end
end
s.bg = bg -- set the background value
else -- fallback value
s.bg = {0,0,0,0}
end
end
if type(update) == 'function' then
s.update = update -- set any update functions
end
if type(draw) == 'function' then
s.draw = draw -- set any drawing functions
end
setmetatable(s, scene)
scenes[name] = s -- add the scene!
end
-- Makes the background appear
function scene:drawBG()
if self.bg then
if type(self.bg) == 'table' then
love.graphics.setBackgroundColor(unpack(self.bg))
elseif type(self.bg) == 'userdata' then
love.graphics.draw(self.bg, 0, 0)
end
end
end
-- Gets and draws the active scene background,
-- calls the draw functions if present
-- @param .../arg: any variables not defined globally
function scenes:draw(...)
local active = scenes:getActive()
scenes[active]:drawBG()
if type(scenes[active].draw) == 'function' then
scenes[active].draw(unpack(arg))
end
end
-- Gets and updates the active scene,
-- calls the update functions if present
-- [@param dt: delta time - from parent function]
-- [@param .../args: any global variables not defined in the function itself]
function scenes:update(dt,...)
if not dt then dt = love.timer.getDelta() end
local active = scenes:getActive()
if type(scenes[active].update) == 'function' then
scenes[active].update(dt,unpack(arg))
end
end
-- Make a specific scene active
-- @param name: the identifier of the scene to make active
function scenes:setActive(name)
scenes.active = name
end
-- Tell me the active scene
-- returns: the active scene table
function scenes:getActive()
return scenes.active
end
-- Grab the scene by the passed identifier, set any update functions
-- @param name: the scene name/identifier
-- @param func: update function(s) just like a per scene love.update(dt)
function scenes:setUpdate(name, func)
if scenes[name] then
if type(func) == 'function' then
scenes[name].update = func
end
end
end
-- Grab the scene by the passed identifier, set any draw functions
-- @param name: the scene name/identifier
-- @param func: draw function(s) just like a per scene love.draw()
function scenes:setDraw(name, func)
if scenes[name] then
if type(func) == 'function' then
scenes[name].draw = func
end
end
end
I thought of making an init function available, but seeing as you should set up the scenes in love.load I'm not sure if it's really worthwhile. Anyway, enjoy! (Feedback appreciated!)