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萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章