Created
August 22, 2014 15:15
-
-
Save yurihan/e8931dd0485fb8d65226 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-- 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