Page 1 of 1

Simple Scenes lib

Posted: Tue Jul 26, 2011 10:57 pm
by mattyhex
Long story short, I found myself trying to use the Crafty javascript game engine and found a neat little idea, an inbuilt 'scenes' system, this basically allows one to create multiple different game scenes (or game states) with ease.

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
Also, yes, I based it on AnAL.

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!)

Re: Simple Scenes lib

Posted: Thu Jul 28, 2011 12:22 am
by mattyhex
I can see this has been popular...
Anyway, for anyone interested I've made the init function available, it's called when the scene is set active, I've also updated the scenes.love a bit.

Re: Simple Scenes lib

Posted: Thu Jul 28, 2011 12:33 am
by TechnoCat
I like that you shifted the arrows this time around. Before it was going to the next if mouse was down instead of on mouse down and flashing through really fast.

Just to be sure, you've heard of vrld's HUMP gamestate and Kikito's Middleclass Stateful right?

Re: Simple Scenes lib

Posted: Sat Jul 30, 2011 11:03 pm
by mattyhex
I had a quick look at them just after I'd finished working on the first version. Though personally I like enjoy writing my own.

At some point in time I think I'll try to make a point and click escape game or something similar, my coding ability doesn't really go beyond that right now.