lua实现的有限状态机

       在做的一个项目,由于人物的状态较多,切换比较麻烦不便管理,所以打算引入状态机,方便管理。下面是fsm的简易版本,还有些待完善的地方。

      

local inspect = require "inspect"

local FSMState = {}

function FSMState:new(super)
	local obj = super or {}
	obj.super = self
	return setmetatable(obj, {__index = self})
end


function FSMState:enter()
	print(string.format("%s enter", self.name))
end


function FSMState:exit()
	print(string.format("%s exit", self.name))
end



local FSMStateMachine = {}

function FSMStateMachine:new()
	local obj = {
		idle = FSMState:new{name="idle"},
		walk = FSMState:new{name="walk"},
		attack = FSMState:new{name="attack"},
		event = {
			idle = {},
			walk = {},
			attack = {},
		},
		_curState = "idle",
	}

	return setmetatable(obj, {__index = self})
end

function FSMStateMachine:addTransition(before, input, after)
	if self.event[before] then
		if self.event[before][input] then assert("event already be added")
		else
			self.event[before][input] = after
		end
	end
end

function FSMStateMachine:stateTransition(event)
	assert(self._curState)
	print(self._curState)
	local out = self.event[self._curState][event]
	if out then
		print(string.format("reponse to event:%s", event))
		-- respond to this event
		self[self._curState]:exit()
		self._curState = out
		self[self._curState]:enter()
	else
		-- no related event
		print(string.format("no reponse to event:%s", event))
	end
end

------------------------------------------------------------------
----test
------------------------------------------------------------------
local sm = FSMStateMachine:new()
--print(inspect(sm))
sm:addTransition("idle", "seen player", "walk")
sm:addTransition("idle", "player attack", "attack")
sm:addTransition("walk", "player go away", "idle")
sm:addTransition("attack", "player die", "idle")
--print(inspect(sm))


sm:stateTransition("player attack")
sm:stateTransition("seen player")

     输出的结果:

     

发布了28 篇原创文章 · 获赞 3 · 访问量 8万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章