【游戏功能】
"一把剑是攻击,两把剑是什么?"——是 twice 的快乐,是夹击的艺术。雌雄双剑这套玩法的看点只有一个字:同。两把剑一上一下分飞出去,沿着两条不同的弧线包抄,最后在同一帧从狼怪左右两侧同时命中。单剑命中各算各的,同帧双命中触发"合击",伤害上一个档位。怎么让玩家清清楚楚看见"同一帧"?往下拆。
一、两条弧线与一个时间差
双剑的飞行轨迹是两条对称的贝塞尔弧:雌剑走上方大弧,飞得高、绕得远;雄剑贴着地面走下弧,又低又快。两条弧的路程刻意不等长,但飞行时间完全相同——路径长的早出发,路径短的晚出发,控制好出发时差,两把剑就能同时贴上狼怪。夹击瞬间要做满:接触点两侧同时炸花、冲击环从狼怪身上扩散、屏幕轻震、合击数字比普攻数字大一号并带"合击"前缀。这套表现的关键是"同时"必须精确到帧,差两帧玩家就看成两段普攻了。
完整演示在下面,默认自动循环,可配合击加成:
fx-twinswords
二、幂尔框架实现:时差发射,同帧到达
实现的核心是算两条弧的路程比,再反推出第二把剑的发射延迟。飞行本身用 SL:Schedule 做参数化插值:
local TwinSwords = {}
local KEY = { FLY = 0.55, MERGE_BONUS = 25 }
local swords = nil
local function Bezier(t, p0, c1, c2, p1)
local u = 1 - t
return u*u*u*p0 + 3*u*u*t*c1 + 3*u*t*t*c2 + t*t*t*p1
end
function TwinSwords.Cast(self_, target)
if swords then return end
SL:PlayActorAct(self_, "cast")
local sx, sy = SL:GetValue("actorX", self_), SL:GetValue("actorY", self_)
local tx, ty = SL:GetValue("actorX", target), SL:GetValue("actorY", target) - 58
swords = {
t = 0,
top = { sx=sx+16, sy=sy-64, c1x=sx+110, c1y=sy-190, c2x=tx-120, c2y=sy-190, ex=tx, ey=ty },
bot = { sx=sx+16, sy=sy-40, c1x=sx+130, c1y=sy+46, c2x=tx-90, c2y=sy+46, ex=tx, ey=ty }
}
-- 雄剑晚 0.06 秒出发,抵消下弧路程短的时间差
SL:ScheduleOnce(function() swords.bot.delayDone = true end, 0.06)
SL:Schedule(function(dt)
swords.t = swords.t + dt / KEY.FLY
TwinSwords.Step(target)
end, 0.016, "twinFly")
end
function TwinSwords.Step(target)
local s = swords
local tm = math.min(1, s.t)
local tf = s.bot.delayDone and math.min(1, (s.t * KEY.FLY - 0.06) / KEY.FLY) or 0
s.posTop = Bezier(tm, s.top.sy and 0 or 0, {x=s.top.c1x,y=s.top.c1y}, {x=s.top.c2x,y=s.top.c2y}, {x=s.top.ex,y=s.top.ey})
if tf >= 1 and tm >= 1 and not s.merged then
s.merged = true
SL:UnSchedule("twinFly")
local bonus = KEY.MERGE_BONUS
SL:ScreenShake(0.26, 4)
SL:ShowHitNum(target, 26 + bonus, "merge")
SL:PlayActorAct(target, "stuck")
SL:ShowSystemTips("同帧双命中! 合击+" .. bonus .. "%")
SL:ScheduleOnce(function() swords = nil end, 0.5)
end
end
return TwinSwords
那 0.06 秒的出发时差就是整套手感的灵魂,差一点合击就散。
三、数字的层级与合击仪式感
合击数字和单剑数字必须拉开层级:单剑命中是小号白字往斜上飘,合击是大号蓝字、先放大两成再回弹、原地停 0.2 秒才走——玩家扫一眼就知道刚才那一下"不一样"。再讲究一点,合击瞬间让两把剑在狼怪身上交汇处闪一个十字光斑,光斑转 45 度淡出,这个符号会慢慢变成玩家认合击的视觉锚点。
最容易翻车的细节是双剑回收。命中之后剑去哪了?很多实现让剑原地消失,非常浪费——加一段 0.3 秒的归鞘回旋(各自沿小弧线飞回角色身侧,渐隐),回收动画本身就是一套免费的表演,还能天然当下一轮施法的冷却视效。剑在空中飞的时候角色本体一定要锁在收招姿势,见过剑还在飞、人已经满地跑的实现,像放了风筝忘了收线。
全站技术干货持续更新:996 引擎 / Lua 实战帖,语法、参数与示例一篇讲透。进入文章地图 · 查看全部 →
【游戏功能】 heat = heat + 1; if heat = 3 then rest = 1.6 ——两行管刀温的代码…
【游戏功能】 兄弟俩打一只狼,哥哥攒了三层劲自己放,一层加二十五;弟弟站在旁边干瞪眼——直到有人把劲递了过去:同样的三层,过…
【游戏功能】 有篇纠错单写得像小说:同一只狼,有人打它半小时血线稳如老狗,有人三分钟放倒——排查到最后发现,会打的那个从头到…
【游戏功能】 追着你满场跑的狼怪,为什么绕过一根石柱就懵在原地?脱影的答案藏在柱子背后:视线被石柱掐断一秒二,它脑子里"你"…
【游戏功能】 巡查群里有人喊邪门:同一套连招,昨天刀刀见血,今天刀刀被挡——查录像看到第三遍才看懂:狼怪学会了。他的出刀间隔…
【游戏功能】 if hand == last then acid = acid + 1 ——一行数手的判定,攒出了换手全部的…