79 lines
1.8 KiB
Lua
79 lines
1.8 KiB
Lua
-- behavior.lua -- a state manager
|
|
|
|
-- internal/external api
|
|
|
|
local function getCurrentFrame (behavior)
|
|
return behavior.states[behavior.state][behavior.index]
|
|
end
|
|
|
|
local function advanceFrame (behavior)
|
|
local nextState = behavior.frame.after
|
|
local nextIndex = behavior.index + 1
|
|
local maxIndex = #behavior.states[behavior.state]
|
|
|
|
if nextState then
|
|
behavior.state = nextState
|
|
nextIndex = 1
|
|
elseif nextIndex > maxIndex then
|
|
nextIndex = 1
|
|
end
|
|
|
|
behavior.index = nextIndex
|
|
behavior.frame = behavior:getCurrentFrame()
|
|
end
|
|
|
|
local function performAction (behavior)
|
|
local act = behavior.frame.action
|
|
|
|
if act then
|
|
act(behavior, behavior.subject)
|
|
end
|
|
end
|
|
|
|
-- external api
|
|
|
|
local function update (behavior, dt)
|
|
behavior.elapsed = behavior.elapsed + dt
|
|
|
|
while behavior.elapsed >= behavior.frame.duration do
|
|
behavior.elapsed = behavior.elapsed - behavior.frame.duration
|
|
behavior:advanceFrame()
|
|
behavior:performAction()
|
|
end
|
|
|
|
return behavior
|
|
end
|
|
|
|
local function setState (behavior, state, index)
|
|
behavior.state = state
|
|
behavior.index = index or 1
|
|
behavior.elapsed = 0
|
|
behavior.frame = behavior:getCurrentFrame()
|
|
behavior:performAction()
|
|
return behavior
|
|
end
|
|
|
|
-- behavior factory
|
|
|
|
return function (states, subject)
|
|
local behavior = {
|
|
states = states,
|
|
subject = subject,
|
|
elapsed = 0,
|
|
state = 'default',
|
|
index = 1,
|
|
-- internal api
|
|
getCurrentFrame = getCurrentFrame,
|
|
advanceFrame = advanceFrame,
|
|
performAction = performAction,
|
|
-- external api
|
|
update = update,
|
|
setState = setState
|
|
}
|
|
|
|
behavior.frame = behavior:getCurrentFrame()
|
|
behavior:performAction()
|
|
|
|
return behavior
|
|
end
|