Page 1 of 1
I want to make my own gamestate library.
Posted: Fri Oct 05, 2012 6:55 pm
by Tesselode
I want to have a gamestate library that works like this:
Code: Select all
state = gamestate.new()
function state:load()
end
function state:update(dt)
end
The problem is I'm not sure how to link the gamestate functions to the love callbacks. I know it has something to do with metatables, but how exactly do you detect when a callback function is called?
Re: I want to make my own gamestate library.
Posted: Fri Oct 05, 2012 7:19 pm
by SudoCode
You could probably get a good idea by looking through the existing gamestate libs. hump, maybe.
Re: I want to make my own gamestate library.
Posted: Fri Oct 05, 2012 7:50 pm
by Inny
The trick to "States" is the "StateMachine" that drives the states. In short, you have to have the lua callbacks call into the state machine. Here's a short example:
Code: Select all
GameState = {}
function GameState:update(dt) end
Statemachine = { current=GameState }
function Statemachine:update(dt)
self.current:update(dt)
end
function love.update(dt)
Statemachine:update(dt)
end
In my own personal projects, I like having the StateMachine be a stack/queue combination, meaning that I can ready a state that will start on the next update cycle, and then the states can send updates via the statemachine to each other. In practice, it means I can still have the GameState draw, even though the OptionsMenuState is at the top of the stack.
Re: I want to make my own gamestate library.
Posted: Fri Oct 05, 2012 7:54 pm
by IMP1
The way I do it is this:
In another file, have your state:
Code: Select all
local state = {}
state.__index = state
function state.load()
local this = {}
setmetatable(this, state)
-- this is the basic table that represents the state
-- so initial values for properties of the state would be set here
return this
end
function state:update(dt)
-- update state here
end
function state:draw()
-- draw state here
end
-- any other functions
return state
And in your main.love you'd have this:
Code: Select all
gamestate = require("path.to.your.state")
function love.load()
state = gamestate.new()
end
-- etc. with update.
Re: I want to make my own gamestate library.
Posted: Fri Oct 05, 2012 8:05 pm
by Tesselode
So far all of the suggestions require that you manually call functions for the current state in each callback. Is there a way I can automatically have it do:
Code: Select all
function love.load()
current_state.load(dt)
end
function love.update(dt)
current_state.update(dt)
end
etc...
I know hump.gamestate does this with the registerEvents function, I'm just not sure how.
Edit: If I am reading the hump.gamestate code correctly, this is where all the magic happens:
Code: Select all
for _, f in ipairs(callbacks) do
love[f] = function(...) GS[f](...) end
end
Re: I want to make my own gamestate library.
Posted: Fri Oct 05, 2012 11:26 pm
by Kadoba
Basically it's just a shortcut for exactly what you were doing.
Code: Select all
function love.load()
current_state.load(dt)
end
function love.update(dt)
current_state.update(dt)
end
function love.draw()
current_state.draw()
end
-- Same as above
local callbacks = {"load", "update", "draw"}
for k,v in pairs(calllbacks) do
love[v] = function(...)
if current_state[v] then current_state[v](...) end
end
end
Re: I want to make my own gamestate library.
Posted: Fri Oct 05, 2012 11:26 pm
by Inny
It's more or less the norm to expect love.update call your library's update function. Love has no way to automatically register an event handler other than overwriting love.update.
For fun, you could have a function, or table with a __call or __index metatable, that does some basic routing of messages.
Code: Select all
Statemachine = setmetatable({}, {
__index = function(self, message)
if not self[message] then
self[message] = function(...)
current_state[message](...)
end
end
return self[message]
end
})
With this, it'll automatically generate the update, draw, keypressed, and so on event handlers as you need them. But I consider it a toy rather than something to base a library on.