【游戏功能】
一、先抛一个坑
为什么明明有受击动画,玩家还是觉得"打上去没感觉"?把受击动画逐帧看一遍:两帧,后仰,结束——动画本身没问题,问题在它不拦着任何事。挨打的角色继续跑位、继续抬手、继续施法,受击动画只是叠在身上的一层贴纸。真实的打击感来自停顿:挨那一下,人要愣半拍。这半拍在格斗游戏里叫硬直,在传奇类客户端里,它是受击表现的核心而非附件。
二、机制原理:硬直是移动与动作的暂停键
硬直的实现不是播一段动画,而是按住两个开关:移动冻结——硬直时间内位移逻辑跳过,人定在原地;动作打断——普通动作(攻击、施法、采集)被受击覆盖,正在播的清零。受击动作本身很短,两帧的后仰配合冻结,加一点受击方向的白闪,挨打的"重量感"就出来了。硬直时长是手感参数:零点三秒以下像挠痒,零点六秒以上像读条,零点四五秒上下是安全区。
mir8-hurt
三、正确写法:硬直窗口的冻结与恢复
local HURT_STIFF_TIME = 0.45
function gameActor:OnAttackHit(data)
if self._dead or self._uninterruptible then return end
self._hp = self._hp - data.damage
if self:CanStiff() then -- boss/霸体可免硬直
self._stiffUntil = global.now + HURT_STIFF_TIME
self._moveTarget = nil -- 冻结: 目的点作废
self._casting = nil -- 打断: 施法/攻击清零
self:PlayAction(global.MMO.ANIM_STUCK)
self:PlayHurtFlash()
end
self:PopupDamage(data.damage)
end
function gameActor:UpdateMove(dt)
if self._stiffUntil and global.now < self._stiffUntil then
return -- 硬直中: 位移整体跳过
end
self._stiffUntil = nil
-- ...正常移动
end
四、四个必须钉死的细节
五、心法:打击感是被按住的那半拍
所有打击感的配方都是同一句话:快慢对比。攻击快、受击顿,挥刀零点二秒、挨刀愣半拍,快慢差就是打击感的全部来源。帧动画负责快,硬直负责慢,白闪和飘字负责把这一慢标注出来。想调手感的策划不该去改动画,该来调那零点四五秒——它是战斗节奏的节拍器,是全组最值得反复试的一个数字。
顺带一个鉴别口诀:拉两个打同样的号,一个开硬直一个不开,让十个玩家盲评哪个"打得疼"。十个人九个选开硬直的那个,剩下一个没看懂规则。打击感从来不是玄学,它就是这半拍在起作用——动画组交多少素材来,程序这边这半拍不接住,素材就白画了。
全站技术干货持续更新:996 引擎 / Lua 实战帖,语法、参数与示例一篇讲透。进入文章地图 · 查看全部 →
【语法算法】 元方法 __close 的错误传递就这两行: to-be-closed 变量离开作用域时自动调用 __clos…
【语法算法】 goto 向后跳的控制就这一行: ::retry:: 定义标签, goto retry 跳回标签——向后跳的全…
【语法算法】 元方法 __close 的多资源清理就这两行: 两个 to-be-closed 变量——声明的逆序清理——先关…
【语法算法】 随机种子的确定性本质就这一行: 固定种子意味着随机数序列完全确定——同样的种子产生同样的序列——随机种子的全部…
【语法算法】 协程的状态机就这一行: status 返回四种字符串之一:"suspended"、"running"、"nor…
【语法算法】 xpcall 的错误对象就这两行: xpcall 和 pcall 的本质区别就是第二个参数——错误处理函数——…