posts - 311, comments - 0, trackbacks - 0, articles - 0
  C++博客 :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理

class.lua实现了在Lua中创建类的模拟,非常方便。class.lua参考自http://lua-users.org/wiki/SimpleLuaClasses

State基类,包含三个stub函数,enter()和exit()分别在进入和退出state时被执行,onUpdate()函数将会在state被激活时的每帧被执行。

1 require "class"
2
3 State = class()
4
5 function State:init( name )
6 self.name = name
7 end
8
9 function State:enter()
10 end
11
12 function State:onUpdate()
13 end
14
15 function State:exit()
16 end

StateMachine类,该类集成了Moai的MOAIThread类。MOAIThread类似于Lua中的coroutine,但是在Moai中被yield的MOAIThread,会在game loop的每帧中被自动resume,见StateMachine:updateState函数,利用此特点,来实现每帧执行State:onUpdate函数。

1 require "State"
2
3 StateMachine = class()
4
5 function StateMachine:init()
6 self.currentState = nil
7 self.lastState = nil
8 end
9
10 function StateMachine:run()
11 if ( self.mainThread == nil )
12 then
13 self.mainThread = MOAIThread.new()
14 self.mainThread:run( self.updateState, self )
15 end
16 end
17
18 function StateMachine:stop()
19 if ( self.mainThread )
20 then
21 self.mainThread:stop()
22 end
23 end
24
25 function StateMachine:setCurrentState( state )
26 if ( state and state:is_a( State ) )
27 then
28 if ( state == self.currentState )
29 then
30 print( "WARNING @ StateMachine::setCurrentState - " ..
31 "var state [" .. state.name .. "] is the same as current state" )
32 return
33 end
34 self.lastState = self.currentState
35 self.currentState = state
36 if ( self.lastState )
37 then
38 print( "exiting state [" .. self.lastState.name .. "]" )
39 self.lastState:exit()
40 end
41 print( "entering state [" .. self.currentState.name .. "]" )
42 self.currentState:enter()
43 else
44 print( "ERROR @ StateMachine::setCurrentState - " ..
45 "var [state] is not a class type of State" )
46 end
47 end
48
49 function StateMachine:updateState()
50 while ( true )
51 do
52 if ( self.currentState ~= nil )
53 then
54 self.currentState:onUpdate()
55 end
56 coroutine.yield()
57 end
58 end

如何利用State和StateMachine类的示例,首先定义两个state。
SampleState.lua

1 require "State"
2
3 State1 = class( State )
4
5 function State1:init()
6 State.init( self, "State1" )
7 end
8
9 function State1:enter()
10 self.i = 0
11 end
12
13 function State1:exit()
14 self.i = 0
15 end
16
17 function State1:onUpdate()
18 print( self.name .. " is updated" )
19 self.i = self.i + 1
20 print( "self.i=" .. self.i )
21 if ( self.i == 10 )
22 then
23 print( state2 )
24 SM:setCurrentState( state2 )
25 self.i = 0
26 end
27 end
28
29 -----------------------
30
31 State2 = class( State )
32
33 function State2:init()
34 State.init( self, "State2" )
35 end
36
37 function State2:onUpdate()
38 print( "State2 is updated" )
39 end

test.lua

1 require "StateMachine"
2 require "SampleState"
3
4 SM = StateMachine()
5 SM:run()
6 state1 = State1()
7 state2 = State2()
8 SM:setCurrentState( state1 )