Skip to content

Instantly share code, notes, and snippets.

@yurihan
Created August 22, 2014 15:15
Show Gist options
  • Save yurihan/e8931dd0485fb8d65226 to your computer and use it in GitHub Desktop.
Save yurihan/e8931dd0485fb8d65226 to your computer and use it in GitHub Desktop.
-- StateManager.lua
local M = {stateMachines = {},paused = true}
function M:addMachine(fsm)
local index = table.indexOf(self.stateMachines, fsm)
if(index == nil) then
table.insert(self.stateMachines, fsm)
log(fsm.name.." | 상태 머신이 추가되었습니다.")
return true
else
log(fsm.name.." | 이미 존재하는 머신입니다.")
return false
end
end
function M:removeMachine(fsm)
local index = table.indexOf(self.stateMachines, fsm)
if index == nil then
table.remove(self.stateMachines, index)
log(fsm.name.." | 상태 머신이 삭제되었습니다.")
return true
end
log(fsm.name.." | 삭제할 머신이 없습니다.")
return false
end
function M:removeAllMachine()
self.stateMachines = nil
self.stateMachines = {}
end
function M:update(event)
if self.paused then return end
for k,v in pairs(self.stateMachines) do
v:update(event)
end
end
function M:pause()
self.paused = true
end
function M:start()
self.paused = false
end
return M
-- StateMachine.lua
function createStateMachine(owner,name)
local M = {stt = {},state={},currentState='idleState'}
M.owner = owner
M.name = name
-- from -> event -> to
-- stt = {from, name, to}
function M:addStateTransitionTable(stt)
if self.stt[stt.name] == nil then
self.stt[stt.name] = {}
end
table.insert(self.stt[stt.name],{from=stt.from,to=stt.to})
end
function M:addState(state)
self.state[state.name] = state
state.sm = self
end
function M:transition(evt)
for i,v in ipairs(self.stt[evt]) do
if v.from == '*' or v.from == self.currentState then
if self.state[v.to]:canEnterState(v.from,evt) then
self.state[self.currentState]:exitState(v.to,evt)
self.state[v.to]:enterState(v.from,evt)
self.currentState = v.to
return
end
end
end
end
function M:update(event)
self.state[self.currentState]:update(event)
end
return M
end
-- idleState.lua
local M = {}
function M:create(owner)
local MM = {name = "idleState"}
MM.owner = owner
function MM:exitState(to,evt)
log('exitState : '..self.owner.sm.name..' | '..evt..' | '.. self.name ..' -> '..to)
end
function MM:canEnterState(from,evt)
return true
end
function MM:enterState(from,evt)
log('enterState : '..self.owner.sm.name..' | '..evt..' | '.. from ..' -> '..self.name)
end
function MM:update(event)
if event.touchState.isTouched then
self.owner.group.x = event.touchState.x
self.owner.group.y = event.touchState.y
self.sm:transition('moveStart')
end
end
return MM
end
return M
-- example.
-- create State Machine and States
local weapon = display.newGroup()
weapon.sm = createStateMachine(weapon,'weapon')
weapon.sm:addState(require('state.weapon.idleState'):create(weapon))
weapon.sm:addState(require('state.weapon.moveState'):create(weapon))
weapon.sm:addState(require('state.weapon.attackState'):create(weapon))
weapon.sm:addStateTransitionTable({name='moveEnded',from='moveState',to='idleState'})
weapon.sm:addStateTransitionTable({name='moveStart',from='idleState',to='moveState'})
weapon.sm:addStateTransitionTable({name='attackStart',from='moveState',to='attackState'})
weapon.sm:addStateTransitionTable({name='attackEnded',from='attackState',to='moveState'})
weapon.sm:addStateTransitionTable({name='moveEnded',from='attackState',to='idleState'})
-- start State Machine.
stateManager:addMachine(weapon.sm)
stateManager:start()
-- update.
local lastUpdateTime = 0
local function enterFrameHandler(event)
local time = event.time
local dt = (time - lastUpdateTime) / 1000
stateManager:update({dt=dt,touchState=touchState})
lastUpdateTime = time
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment