• About
    • Resume
A Game Developer also plays some guitar

Tag Archives: State Pattern

基于Lua的State Pattern

September 4, 2011 12:56 pm / Benny Chen

代码来自于最近写的Pacman,更多请查看 – https://github.com/bennychen/Moai-based-Pacman

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

-- class.lua
-- Compatible with Lua 5.1 (not 5.0).

function class(base, init)
   local c = {}    -- a new class instance
   if not init and type(base) == 'function' then
      init = base
      base = nil
   elseif type(base) == 'table' then
    -- our new class is a shallow copy of the base class!
      for i,v in pairs(base) do
         c[i] = v
      end
      c._base = base
   end
   -- the class will be the metatable for all its objects,
   -- and they will look up their methods in it.
   c.__index = c

   -- expose a constructor which can be called by <classname>(<args>)
   local mt = {}
   mt.__call = function(class_tbl, ...)
   local obj = {}
   setmetatable(obj,c)

-- below 2 lines are updated based on the Comments from 'http://lua-users.org/wiki/SimpleLuaClasses'
--   if init then
--      init(obj,...)
   if class_tbl.init then
      class_tbl.init(obj,...)
   else 
      -- make sure that any stuff from the base class is initialized!
      if base and base.init then
      base.init(obj, ...)
      end
   end
   return obj
   end
   c.init = init
   c.is_a = function(self, klass)
      local m = getmetatable(self)
      while m do 
         if m == klass then return true end
         m = m._base
      end
      return false
   end
   setmetatable(c, mt)
   return c
end

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

require "class"

State = class()

function State:init( name )
	self.name = name
end

function State:enter()
end

function State:onUpdate()
end

function State:exit()
end

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

require "State"

StateMachine = class()

function StateMachine:init()
	self.currentState = nil
	self.lastState = nil
end

function StateMachine:run()
	if ( self.mainThread == nil )
	then
		self.mainThread = MOAIThread.new()
		self.mainThread:run( self.updateState, self )
	end
end

function StateMachine:stop()
	if ( self.mainThread )
	then
		self.mainThread:stop()
	end
end

function StateMachine:setCurrentState( state )
	if ( state and state:is_a( State ) )
	then
		if ( state == self.currentState )
		then
			print( "WARNING @ StateMachine::setCurrentState - " ..
				   "var state [" .. state.name .. "] is the same as current state" )
			return
		end
		self.lastState = self.currentState
		self.currentState = state
		if ( self.lastState )
		then
			print( "exiting state [" .. self.lastState.name .. "]" )
			self.lastState:exit()
		end
		print( "entering state [" .. self.currentState.name .. "]" )
		self.currentState:enter()
	else
		print( "ERROR @ StateMachine::setCurrentState - " ..
			   "var [state] is not a class type of State" )
	end
end

function StateMachine:updateState()
	while ( true )
	do
		if ( self.currentState ~= nil )
		then
			self.currentState:onUpdate()
		end
		coroutine.yield()
	end
end

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

require "State"

State1 = class( State ) 

function State1:init()
	State.init( self, "State1" )
end

function State1:enter()
	self.i = 0
end

function State1:exit()
	self.i = 0
end

function State1:onUpdate()
	print( self.name .. " is updated" )
	self.i = self.i + 1
	print( "self.i=" .. self.i )
	if ( self.i == 10 )
	then
		print( state2 )
		SM:setCurrentState( state2 )
		self.i = 0
	end
end

-----------------------

State2 = class( State ) 

function State2:init()
	State.init( self, "State2" )
end

function State2:onUpdate()
	print( "State2 is updated" )
end

test.lua

require "StateMachine"
require "SampleState"

SM = StateMachine()
SM:run()
state1 = State1()
state2 = State2()
SM:setCurrentState( state1 )
Posted in: Game Programming, Lua / Tagged: finite state machine, FSM, lua, state pattern, 状态模式

LinkedIn

Milan Petrovic

Categories

  • In My Life (25)
    • A Day in the Life (8)
    • English Learning (2)
    • Learn a Word (7)
    • Something In The Way (8)
  • Music Heaven (8)
    • Guitar (1)
    • In Concert (1)
    • Lyrics (3)
  • OK Computer (54)
    • 3D (3)
    • C++ (10)
    • Computer Graphics (15)
    • Game Programming (23)
    • iOS (6)
    • Linux (1)
    • Lua (9)
    • My Projects (3)
    • Some Experiences (9)
    • Talking in Code (2)
    • Unity (2)
  • Quotations (2)
  • Uncategorized (1)
  • Visca Barça (24)
    • FCB BJ (5)

Recent Posts

  • [译]优化你的手机游戏(没有延迟的,才是健康的)- 一篇给游戏美术设计师读的文章
  • 新浪微博API for MOAI
  • 稍后继续
  • Unity Developer ++
  • Another Thread @ Moai Forum
  • 1st Day of Golden Week
  • 为SyntaxHighlighter添加新语言
  • 基于Lua的State Pattern
  • Class Diagram of Pacman
  • 基于Moai的Pacman

Recent Comments

  • 约修亚_RK on 为SyntaxHighlighter添加新语言
  • 爱装的小男孩 on 小心DLL链接静态库时的内存错误
  • happyfire on Game Loop的几种实现方式
  • William on 新浪微博API for MOAI
  • Benny Chen on 新浪微博API for MOAI
  • your man on 新浪微博API for MOAI
  • 你家男人 on 稍后继续
  • 逍遥 on 关于对std::vector的遍历
  • papa on Unity Developer ++
  • T客网 ︱ Techpot » Blog Archive » iOS开发与OpenGL ES相关问题整理(1) on iOS开发与OpenGL ES相关问题整理(1)

Tags

2d 3D 3dsmax 3ds max air Apply architecture Asia tour barca Beijing bilbao binary search blocked bob boost bruce springsteen C++ capo CGContextDrawImage Champions League Change DLL DX10 eval exporter flash framework frustum culling game game engine iniesta ios linux lua Moai opengles pacman plug-in plugin 北京 导出插件 崩溃 巴萨 游戏引擎 踢球
© Copyright 2026 - A Game Developer
Infinity Theme by DesignCoral / WordPress