|
|
-- 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[from] then self._transitions[from] = {} end
self._transitions[from][event] = { to = to, action = action }
end
function FSM nEnter(state, fn) self._onEnter[state] = fn end
function FSM nExit(state, fn) self._onExit[state] = fn end
-- 触发事件
function FSM:trigger(event, ...)
local trans = self._transitions[self._state]
if not trans or not trans[event] then
print("[FSM] 当前状态 " .. self._state .. " 无法处理事件 " .. event)
return false
end
local t = trans[event]
if self._onExit[self._state] then self._onExit[self._state](self._state) end
if t.action then t.action(...) end
self._state = t.to
if self._onEnter[self._state] then self._onEnter[self._state](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 nEnter("fighting", function() StartTimer(600, function() dungeon:trigger("timeout") end) end)
dungeon nEnter("idle", function() print("副本已重置,等待下次开启") end)
-- 玩家触发开启
dungeon:trigger("start")
-- Boss死亡回调
dungeon:trigger("boss_die")
-- 结算
dungeon:trigger("end")
|
|