【游戏功能】
隐蔽报错引入:一个很隐蔽的错——焰环明明滚到了怪的身上,血条却纹丝不动,玩家骂这环是画的。查了半天,环的碰撞判定量的是侠客到怪圆心的距离,忘了把怪自己的身位半径减掉,环每回都差着十来像素才判中,怪早就走过去了。这篇把烈焰环纹整套写法重写成篇:起环、滚环、撞身结账、环散归零,一段一段照抄能跑。
一、效果演示
演武场是一片烧焦的裂地,怪走进来站定。点「焰环!」——一圈火环自侠客脚下滚出去,贴着地皮越滚越大,滚到怪身上那一下轰地燎开,二十点一片,火星四溅。环撞过身之后光转淡,滚出场外才散,十秒一滚。环滚多大、滚多快,你盯着看就有数。
flowchart TD
A[焰环!] --> B[火环自脚下起]
B --> C[贴地越滚越大]
C --> D{滚到怪身了吗}
D -- 没有 --> C
D -- 到了 --> E[燎开 二十点]
E --> F[光转淡 滚出场散 十秒再滚]
fx-crest-flamering
二、底层原理
烈焰环纹的机关是「滚到才结账」——火环不是一个定点爆的范围技,它是一张会自己走路的账页:环从侠客脚下起,贴着地皮往外滚,半径一寸寸变大,滚到怪的身位那一下才结这一笔二十点。这条机关的要害在碰撞判定的减法:判的从来不是圆心到圆心的距离,而是这个距离再减去怪的身位半径——差的就是这十来像素,早年那单「环是画的」的错案就栽在这儿。环撞过身之后不消失,光转淡继续往外滚,滚出场外才算走完,这样玩家能看见这一环的完整行程,知道账是在哪儿结的。幂尔框架这边,环只放一个半径量,每拍加一步,判中置一个标记,标记翻过脸环就再不重复结账。
这套玩法的代码量不到七十行,难的不是起环那一下,难的是碰撞判定的减法——圆心距离减去怪的身位半径,差的十来像素就是「环是画的」和「环是真的」的全部距离。
焰环的行程给了「滚」字一个完整的样貌:起手小环贴脚,中段撑到半场,撞身燎开再淡出,滚出场才算走完——玩家看着这一环,就知道账在哪儿结的、结了多少。
再补一句关于滚速的话——环的滚速也不能一成不变:起手慢半拍给玩家看清起环,中段提速追怪,撞身那一下再顿一瞬让燎开的爆花站稳,快慢三段全在一根半径量上派生,玩家看着不觉,手感里全有。
起环的位子也有一层说法——环永远从侠客脚跟起,不从脚尖起:脚跟起环,环滚到怪身上的行程比脚尖起环多半尺,这半尺就是给玩家挪位子的余量;若从脚尖起,环起得快,可玩家刚出完刀的收势还没站稳,环已经滚出去了,追不上也收不回。起手位子往后让这么一点,滚出去的每一步都从容。
还有一层是燎开的爆花朝向:火星溅开不是圆的,是朝着怪身后的方向偏——环撞上身,劲道顺着滚的方向穿过怪身,火星往前赶,玩家看着就知道这一环是从哪个方向碾过去的。
三、核心代码:完整模块(上·骨架)
-- @file crest-flamering.lua
-- 烈焰环纹:火焰滚成环,燎它一大片
local M = {}
local CONST = { AUTOINC_BASE = 1212300 }
local _autoInc = 0
local function ShowTip(msg) if msg and msg ~= "" then SL:ShowSystemTips(msg) end end
local function GenID() _autoInc = _autoInc + 1 return CONST.AUTOINC_BASE + _autoInc end
function M.Ready() return true end
四、核心代码:完整模块(下·推进与卸载)
-- 每拍推进: 环滚与撞身
if not _ticker then
_ticker = SL:Schedule(function(dt)
if not _on then return end
_r = _r + 250 * dt
if not _hit and _mx - _px - _mrad <= _r then
_hit = true
ShowTip("燎开——二十点!")
end
if _r > 620 then _on = false ShowTip("环散了") end
end, 0.02)
end
SL:ScheduleOnce(function()
SL:BindDebugButton("焰环!", function()
if _on then ShowTip("环还在滚") return end
_on = true _r = 26 _hit = false
ShowTip("烈焰环——滚过去了!")
end)
end, 1.0)
function M.Unload() _on = false _r = 0 _hit = false end
return M
五、机制问答
问:环滚到怪身上为什么不掉血?
答:查身位半径——判定要拿圆心距离减去怪的身位半径,不减就每回都差十来像素,环成了画的。
问:环撞过身之后去哪了?
答:继续往外滚——光转淡不再结账,滚出场外才散。
问:一环能结几次账?
答:一次——撞身置标记,标记翻脸就不再记第二笔。
问:十秒一滚管什么?
答:焰环的回气。
问:环滚多快?
答:每秒二百五十像素——半场三秒滚完,快得能追上慢走的怪。
六、调参与实战怎么用
参数四个量——起环半径、滚速、单次燎伤、回气。二十六像素、每秒二百五十像素、二十点、十秒是一组甜点位:半场三秒滚到,追得上慢怪追不上急怪,逼人算提前量。想调凶些先把滚速抬到三百——环追得上怪了,燎伤反倒可以降到十六,账少了味道更贴身。
补一句设计层面的话——这六手全在「距离」上做文章:焰环把账滚过去、天雷把账从天上送下来、牙口把两条命的账拴在一刀上、追魂索把远账拽成近账、托举把地面账吊成空中账、火山印把当下的账赊成三秒后的账——远近高低各不同,玩家换着用,取舍才有味道。
补一句维护层面的话——凡是动了怪的位子和状态的机制,收势都要立字据:索要松、怪要落地、印要炸净、环要散、雷要停、牙口要闭,卸载口里一一还原。半空的怪、不灭的印、挂着被拽标记的怪,全是没还完的债。
补一句工程层面的话——凡是「滚到才结、劈到才结、到点才炸」的延迟账,触发时刻只能有一个裁判:判定就读那一份状态量,别在两处各判各的——两处判,必有双爆或漏爆,玩家两头都要骂。
这一手在实战里的分量在「改局」不在「改数」:环逼怪挪步、索把怪拽离站位、举让怪的四秒作废、印逼怪对表——伤是明账,局是暗账,会算暗账的人,明账才下得去手。
反馈要成对:环滚有光影、雷劈有白闪、回血有绿字、拽索有尘土、浮空有金屑、印炸有震屏——视觉给一半,数字给一半,玩家对状态的感知才是完整的。
最后说实战:这类机制的拍点都在怪的抬爪前摇里——环在它迈步时滚、印在它赶路时拍、举在它蓄力时托、索在它退半步时收,掐住前摇,一拍顶三拍;不看前摇乱放,三手不顶一手。
写完留一句给做环系的同学:滚到才结账——判定记得减怪的身位半径,差的十来像素就是真的和画的距离。
全站技术干货持续更新:996 引擎 / Lua 实战帖,语法、参数与示例一篇讲透。进入文章地图 · 查看全部 →
接手二开的兄弟几乎都撞过同一堵墙:玩家嫌走路"一格一格像机器人",老板拍板要"丝滑移动",改服务端速度?不对。改客户端动画帧…
【游戏功能】 先看一个熟场面:法师的火球特效挂在怪的脚后跟上,明明技能说明写着"焚烧其面",火星子却在地上打滚。群里有位策划…
【游戏功能】 上周有个开服的老板在群里发了一段录屏:他的战士明明刀刀都砍中了,观众却一片"这刀挥空了吧"。他原话是"判定日志…
【游戏功能】 先说结论放在开头:怪的皮一会儿绿一会儿红,不是美术换了几套贴图,是染色系统在怪身上盖了一层"色镜"。开服群里有…
前两天群里有个架设的朋友问了个需求:中毒的人要变绿、每两秒掉一次血、毒还能叠五层,问是不是要在服务端把整套状态机重写。我说你…
【游戏功能】 先抛一个坑:五口钟一模一样大,为什么一口比一口疼?先后次序动不得吗?倒过来敲会怎样?这篇把编钟纹整套写法拆开:…