【游戏功能】
一、一次躺不平的死亡
沙巴克攻城战首晚的战报截图里最扎眼的一幕:城门口躺了二十个战士,其中六个还保持着挥手施法的姿势——死亡动作只播了半截就被后续的受击消息打断了,尸体定格在半躺不躺的诡异角度。玩家管这个叫"诈尸"。死亡是角色一生中最重要的一次表现,它却被当成普通动作排队播放,谁都能插队,这就是躺不平的根源。
二、机制原理:终态动作的优先级
死亡动作在动作系统里要享受两个特权:不可打断与末帧锁定。不可打断指一旦进入,受击、冰冻、击飞全部失效——人都要死了,没有比死更高级的中断;末帧锁定指播完停在最后一帧,尸体是这张定格画面本身,不需要额外资源。复活则用倒播实现:把死亡帧序从末帧倒着走回第一帧,起身的过程天然和倒地的过程镜像,节奏严丝合缝,美术一张图都不用多画。
mir8-death
三、正确写法:不可打断的终态与倒播起身
function gameActor:EnterDead()
self._uninterruptible = true -- 终态: 一切打断失效
self._keepLastFrame = true
self:PlayAction(global.MMO.ANIM_DIE)
self:LockAllInputs()
end
function gameActor:OnActionMsg(act)
if self._uninterruptible then return end -- 死亡中不接受任何动作消息
-- ...正常动作分发
end
-- 复活 = 死亡帧序倒放
function gameActor:Revive()
self._reviving = true
self._frameDir = -1 -- 帧步进取负
self._keepLastFrame = false
self:PlayAction(global.MMO.ANIM_DIE)
end
function gameActor:OnFrameAdvance()
local n = self:GetFrameCount(global.MMO.ANIM_DIE, self._dir)
self._frameIndex = self._frameIndex + self._frameDir
if self._reviving and self._frameIndex <= 0 then -- 退回首帧 = 起身完成
self._reviving = false
self._frameDir = 1
self._uninterruptible = false
self:PlayAction(global.MMO.ANIM_IDLE)
self:UnlockAllInputs()
end
end
四、四个必须钉死的细节
五、心法:把最重要的表现做成不可侵犯
死亡、大招演出、剧情镜头,这些一生放不了几次的表现,值得用最高的优先级保护:进入即锁、期间免打断、退出走完整退场。反过来说,如果一个表现可以被任何随机事件打断,就要做好它在玩家眼里从来就没完整播过的准备。终态思维不是死亡专属,是所有"仪式性表现"的通用骨架。
全站技术干货持续更新:996 引擎 / Lua 实战帖,语法、参数与示例一篇讲透。进入文章地图 · 查看全部 →
【语法算法】 元方法 __close 的错误传递就这两行: to-be-closed 变量离开作用域时自动调用 __clos…
【语法算法】 goto 向后跳的控制就这一行: ::retry:: 定义标签, goto retry 跳回标签——向后跳的全…
【语法算法】 元方法 __close 的多资源清理就这两行: 两个 to-be-closed 变量——声明的逆序清理——先关…
【语法算法】 随机种子的确定性本质就这一行: 固定种子意味着随机数序列完全确定——同样的种子产生同样的序列——随机种子的全部…
【语法算法】 协程的状态机就这一行: status 返回四种字符串之一:"suspended"、"running"、"nor…
【语法算法】 xpcall 的错误对象就这两行: xpcall 和 pcall 的本质区别就是第二个参数——错误处理函数——…