tibaiwan1888 发表于 2026-6-4 23:58:07

[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")


qq154886255 发表于 2026-6-5 10:18:26

快了快了,马上就能用VV了
页: [1]
查看完整版本: [Lua] 用状态机(FSM)管理副本流程,彻底告别 if/else 地狱