【游戏功能】
一、一行代码拆解
ctx.arc(0, 0, 58, startAngle, startAngle + sweep)——刀光的全部本体就是这一段圆弧。剩下的都是包装:三层不同粗细不同颜色的描边叠在一起,最里白色当刃口、中间亮蓝当刃身、外层深蓝当辉光,再开加色混合让它在暗背景上发亮,扫过角度随时间推进,一条弧就活了。美术资源紧张的时候,程序画刀光十分钟出效果,而且弧度、宽度、速度全是参数,策划能自己调到满意为止。
二、机制原理:弧的三要素
手绘刀光由三个参数定义身份:弧度决定"劈了多大一片",横斩弧度小速度快,斜劈弧度大速度慢,观感完全不同;扫掠方向决定从哪个角度进、哪个角度出,配上正反交替就是三连斩的节奏;三层描边的配比决定锋利感——白芯要细,占总宽两成,剩下的宽度给光晕,光晕越厚刀越"钝重"、越薄刀越"锋利"。挥砍进度线性推进弧的结束角,起点角保持不动,一根弧像扇子一样打开,这就是挥刀的全部动态。
fx-slash
三、正确写法:引擎侧的弧光实现
-- 用 DrawNode 画三层弧, 挂进度驱动
function CreateSlashEffect(pos, dir, config)
local node = cc.DrawNode:create()
node:setPosition(pos)
local layers = {
{ color = cc.c4f(1, 1, 1, 0.9), width = config.width, r = 58 },
{ color = cc.c4f(0.6, 0.85, 1, 0.6), width = config.width * 0.65, r = 58 + config.width * 0.4 },
{ color = cc.c4f(0.28, 0.5, 1, 0.4), width = config.width * 0.4, r = 58 + config.width * 0.8 },
}
local progress = 0
local function redraw()
node:clear()
local sweep = config.arc * progress
for _, L in ipairs(layers) do
node:drawDot(cc.p(0, 0), 0, L.color) -- 占位保渲染
node:drawArc(cc.p(0, 0), L.r, -0.8, -0.8 + sweep, 80, L.color)
end
end
schedule(node, function(dt)
progress = math.min(1, progress + dt / config.duration)
redraw()
if progress >= 1 then node:removeFromParent() end
end, 1 / 30)
if dir < 0 then node:setScaleY(-1) end
return node
end
四、四个必须钉死的细节
五、心法:能用几何画的表现别等资源
弧光、光圈、弹道拖尾、指向箭头,这一族"几何形发光体"都是几行画图代码的事,特性是参数化彻底——策划随时调,改完即时生效,不排队等美术。把手绘特效库当成美术资源的平替层和原型层:资源没到位先用几何顶着,资源到位了逐个替换,表现永远不断档。刀光这种一闪而过的东西,玩家记住的是节奏和亮度,未必分得清是画的还是贴的。
全站技术干货持续更新:996 引擎 / Lua 实战帖,语法、参数与示例一篇讲透。进入文章地图 · 查看全部 →
【语法算法】 元方法 __close 的错误传递就这两行: to-be-closed 变量离开作用域时自动调用 __clos…
【语法算法】 goto 向后跳的控制就这一行: ::retry:: 定义标签, goto retry 跳回标签——向后跳的全…
【语法算法】 元方法 __close 的多资源清理就这两行: 两个 to-be-closed 变量——声明的逆序清理——先关…
【语法算法】 随机种子的确定性本质就这一行: 固定种子意味着随机数序列完全确定——同样的种子产生同样的序列——随机种子的全部…
【语法算法】 协程的状态机就这一行: status 返回四种字符串之一:"suspended"、"running"、"nor…
【语法算法】 xpcall 的错误对象就这两行: xpcall 和 pcall 的本质区别就是第二个参数——错误处理函数——…