【游戏功能】
连击值攒着有什么用?多数战斗的答案是攒个伤害加成——气势给了第二个答案:攒的是一支军队的士气。每一刀涨十二点、四档封顶、每档给普攻加一成;挨一刀掉五十——连击涨势、挨打掉势;攒到五十可以按「提气」花五十气势换五十血。这篇的核心代码照引擎技能脚本的全规格写:配置表、气势档构件、攻防双向钩子、定时器、调试按钮。
一、效果演示:四档气焰,一念之间
演示场的血条上方多挂四格橙色的气势档。每一刀命中涨十二点、亮一格,四格全亮周身腾起气焰——普攻乘一点四;大怪反手一刀拍过来:气势当场掉五十、两格当场熄灭,掉势的灰字比伤害的数字更扎眼。掉势的灰字比伤害的数字更扎眼——疼是这一刀的本分,掉势是这一刀的利息,两笔账同帧入册。攒到五十以上点「提气!」:五十气势换五十血——血条回涨、气势熄半,攻与血之间当场换算。演示里打两轮:一轮只顾输出从不提气——气势满档打得很爽但血条见底;一轮勤提气——刀软了两档但活得踏实。两种打法的差值就是这门机制要教的经济。两种打法的差值就是这门机制要教的经济——气势 经济收支表写在头顶四格上。
fx-momentum
二、底层原理:一条涨落曲线加一个花销出口
模块的账本是一条涨落曲线。涨侧:命中钩子每次加十二、封顶一百;落侧:受击钩子直接扣五十——涨是细水、落是决口,不对等的涨落让"保持高气势"成为一种进攻性的活法:你可以站着挨打掉光,也可以连着出手把势顶满。花销出口:提气按钮把五十气势兑换成五十血——气势第一次从加成数值变成了可花的货币。两个出口的定位要分清:档位加成是"存的利",提气回血是"花的本"——只存不花的玩家白挂四档气焰,只花不存的玩家永远没有血见底时的那口底气。
三、核心代码:完整模块(上·骨架)
--------------------------------------------------------------------------------
-- @file Momentum.lua
-- @brief 气势 —— 连击涨势 挨打掉势 提气回血五十
-- 客户端表现模块:配置表 / 气势档构件 / 攻防钩子 / 定时器
--------------------------------------------------------------------------------
local Momentum = {}
--------------------------------------------------------------------------------
-- 配置与常量
--------------------------------------------------------------------------------
local CONST = {
MOM_CAP = 100, -- 气势封顶一百
MOM_PER_HIT = 12, -- 一刀十二
LOSE_ON_HIT = 50, -- 挨一刀掉五十
TIER_SIZE = 25, -- 二十五一点
TIER_AMP = 0.1, -- 每档加一成
HEAL_COST = 50, -- 提气五十
HEAL_AMOUNT = 50, -- 换血五十
HEAL_CD = 3.0, -- 提气冷却
-- 颜色
COLOR_MOM = "#ff9f43", -- 气焰
COLOR_DEEP = "#7a3a0e", -- 深焰
COLOR_GHOST = "#ffe0c2", -- 气白
ZORDER_GROUND = 118,
ZORDER_MOM = 131,
ZORDER_EFFECT = 135,
AUTOINC_BASE = 948000,
}
--------------------------------------------------------------------------------
-- 模块内部状态
--------------------------------------------------------------------------------
local _mom = 0 -- 气势读数
local _healCd = 0
local _scheduler = nil
local _autoInc = 0
local m_cos = math.cos
local m_sin = math.sin
--------------------------------------------------------------------------------
-- 辅助函数
--------------------------------------------------------------------------------
local function GenID(prefix)
_autoInc = _autoInc + 1
return string.format("%s_%d", prefix or "MTM", CONST.AUTOINC_BASE + _autoInc)
end
local function GetMyPos()
local x = SL:GetValue("ACTOR_POSITION_X", SL:GetValue("USER_ID"))
local y = SL:GetValue("ACTOR_POSITION_Y", SL:GetValue("USER_ID"))
if not x or not y then return nil end
return { x = x, y = y }
end
local function SafeRemove(node)
if node and not GUI:Widget_IsNull(node) then
GUI:removeFromParent(node)
end
end
local function ShowTip(msg)
if msg and msg ~= "" then SL:ShowSystemTips(msg) end
end
---气势档构件:头顶四格
local function CreateTierNode()
local mp = GetMyPos()
if not mp then return end
local node = GUI:Layout_Create(GUI:Attach_SceneF(), GenID("Tier"),
mp.x - 30, mp.y - 105, 0, 0, false)
GUI:setLocalZOrder(node, CONST.ZORDER_MOM)
for t = 0, 3 do
GUI:DrawLine_Create(node, "tier_" .. t, 0, 0, 13, t * 16, 0, t * 16 + 13, 0,
CONST.COLOR_MOM, 230)
end
return node
end
骨架的两处立规。气势读数是数字不是档位数——档位是读数除二十五的商,读数才是本体,存档位丢读数的版本提气扣五十就成了糊涂账。气势档构件四格画死在头顶——档是玩家每一刀的即时反馈,挂在增益栏里的气势没人看。
四、核心代码:完整模块(下·定时器与双向钩子)
--------------------------------------------------------------------------------
-- 涨势与掉势
--------------------------------------------------------------------------------
local function OnNormalHit()
_mom = math.min(CONST.MOM_CAP, _mom + CONST.MOM_PER_HIT)
end
local function OnPlayerHurt(raw)
if _mom >= CONST.LOSE_ON_HIT then
_mom = _mom - CONST.LOSE_ON_HIT
SL:TipAboveMe("势-50")
end
SL:PlayerHurt(raw)
end
--------------------------------------------------------------------------------
-- 提气出口
--------------------------------------------------------------------------------
function Momentum.Cast()
if _healCd > 0 then return end
if _mom < CONST.HEAL_COST then
ShowTip("气势不足五十")
return
end
_mom = _mom - CONST.HEAL_COST
_healCd = CONST.HEAL_CD
SL:HealMe(CONST.HEAL_AMOUNT)
ShowTip("提气换血五十")
end
--------------------------------------------------------------------------------
-- 档位系数与定时器
--------------------------------------------------------------------------------
local function TierAmp()
return 1 + math.floor(_mom / CONST.TIER_SIZE) * CONST.TIER_AMP
end
if not _scheduler then
_scheduler = SL:Schedule(function(dt)
_healCd = math.max(0, _healCd - dt)
SL:SetNextAttackAmp(TierAmp())
end, 0.02)
end
SL:RegisterLUAEvent(LUA_EVENT_LOCAL_HIT, "MTM_Hit", function()
OnNormalHit()
end)
SL:RegisterLUAEvent(LUA_EVENT_LOCAL_HURT, "MTM_Hurt", function(data)
if data and data.raw then
OnPlayerHurt(data.raw)
end
end)
SL:ScheduleOnce(function()
ShowTip("技能已加载: 气势 (调试按钮触发)")
end, 1.0)
return Momentum
下半场的两个钩子是气势的两只手。命中钩子只涨不判——涨势没有条件,每一刀都算数;受击钩子的掉势写在扣血之前、无条件扣五十——气势的账是攻防两本,挨打的刀一边扣血一边扣势,同一帧两笔。气势的账是攻防两本,挨打的刀一边扣血一边扣势,同一帧两笔。档位的音效也要分四级——档越高的出手声越沉,听声辨档的玩家不用抬头。提气出口的双重拦截先冷却后存量,两道都过才换血——换血的同时气势当场清半,血和势的兑换汇率写在 CONST 的两个五十里,一眼可查。
五、调参指南与商业服怎么用
调参三笔账。一刀十二对一百封顶是九刀满势——对一点二秒的普攻是十秒出头攒满,攒势的速度要快过掉势的速度,玩家才敢顶着怪的刀输出。挨一刀掉五十对满格一百是"半管士气一刀拍碎"——掉势狠到这个份上,气势才从数值变成"不能挨打"的理由。提气的汇率一比一是最诚实的定价——气势换血不赔不赚,赚的是"把攻击性资产兑成生存"的那一步灵活。常见坑三个:掉势的五十写死在两处,提气的五十和挨打的五十改了一个忘一个;满档气焰的视觉不随档位衰减,掉势后气焰还烧着;提气冷却挂在了掉势钩子上,挨打把提气的冷却也拍了下去。
商业服里气势是"进攻流派"的段位系统:气势档的边框做成赛季段位——铜档银档金档,输出的积极程度直接写在头顶。气势档的边框做成赛季段位——铜档银档金档,输出的积极程度直接写在头顶。档位的掉落也要有仪式感——熄掉的两格要暗下去而不是消失,暗格提醒玩家刚才那刀亏了多少。副本里它是输出榜的隐藏分:满档时间占比高的玩家输出必然高,气势的保持率就是操作率的影子。气势的保持率就是操作率的影子。满档的气焰视觉再添一层——四档全亮的周身气焰是身份的表示,队友一眼就知道该跟着谁走。变体做成团队气势:全队共享一条气势、一人掉势全队熄——个人连击长成集体士气,行会战的战吼有了数值的根。这一篇的演示和整套模块照抄能跑,改的就是 CONST 那张表。
写完留一句给做连击系的同学:气势卖的是"进攻的复利"——每一刀都在涨、每一次挨打都在跌,玩家的走位从此有了利息。
全站技术干货持续更新:996 引擎 / Lua 实战帖,语法、参数与示例一篇讲透。进入文章地图 · 查看全部 →
【游戏功能】 怪的仇恨为什么永远追着你?因为它看得见你。迷魂香把"看得见"这三个字没收了:一炉香落在它脚下,烟圈六秒——圈里…
【游戏功能】 连击值攒着有什么用?多数战斗的答案是攒个伤害加成——气势给了第二个答案:攒的是一支军队的士气。每一刀涨十二点、…
【游戏功能】 一道割裂挂上去,一秒一跳——它站着跳四,追你的时候崩成八:伤口一动就崩,跑得越快掉得越凶。崩血把"放风筝"从走…
【游戏功能】 突进出去了,回不回得来?多数突进的答案是"不回"——人留在怪堆里听天由命。燕回式给突进装了归途:穿身而过去时一…
【游戏功能】 读条变红的那一秒,全世界都在等一个决定。破招式把这一秒做成整场战斗的心跳:怪交替出红劈和蓝刺,红劈读条时按下破…
【游戏功能】 出招的顺序算不算伤害?大多数战斗里不算——三招乱按和按谱出,账面一个样。连招谱把顺序变成了伤害本身:「劈→撩→…