[Lua] 用状态机(FSM)管理副本流程,彻底告别 if/else 地狱
-- FSM.lua有限状态机local FSM = {}
FSM.__index = FSM
function FSM.new(initialState)
return setmetatable({
_state = initialState,
_transitions = {},-- { fromState = { event = { to, action } } }
_onEnter = {},
_onExit = {},
}, FSM)
end
-- 定义转换规则:from 状态下收到 event,执行 action 后进入 to 状态
function FSM:addTransition(from, event, to, action)
if not self._transitions then self._transitions = {} end
self._transitions = { to = to, action = action }
end
function FSM:onEnter(state, fn) self._onEnter = fn end
function FSM:onExit(state, fn)self._onExit = fn end
-- 触发事件
function FSM:trigger(event, ...)
local trans = self._transitions
if not trans or not trans then
print(" 当前状态 " .. self._state .. " 无法处理事件 " .. event)
return false
end
local t = trans
if self._onExitthen self._onExit(self._state) end
if t.action then t.action(...) end
self._state = t.to
if self._onEnter then self._onEnter(self._state) end
return true
end
function FSM:getState() return self._state end
return FSM
副本流程示例:
local FSM = require("FSM")
local dungeon = FSM.new("idle")
dungeon:addTransition("idle", "start", "prepare", function() BroadcastMap("副本准备中,30秒后开始!") end)
dungeon:addTransition("prepare", "timeout", "fighting",function() SpawnBoss("魔王") end)
dungeon:addTransition("fighting","boss_die","reward",function() OpenChest("宝箱", 3) end)
dungeon:addTransition("fighting","timeout", "failed",function() KickAllPlayers() end)
dungeon:addTransition("reward","end", "idle", function() ResetMap() end)
dungeon:addTransition("failed","end", "idle", function() ResetMap() end)
dungeon:onEnter("fighting", function() StartTimer(600, function() dungeon:trigger("timeout") end) end)
dungeon:onEnter("idle", function() print("副本已重置,等待下次开启") end)
-- 玩家触发开启
dungeon:trigger("start")
-- Boss死亡回调
dungeon:trigger("boss_die")
-- 结算
dungeon:trigger("end")
快了快了,马上就能用VV了
页:
[1]