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?
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:
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.
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
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:
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
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.
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.