【游戏功能】
上个月一场追猎事故把地图设计组问住了:一只追风豹咬着一个玩家从东门追到西门,横穿三张地图没停——仇恨的绳没有长度,它认准了就能跑遍全世界。绳的另一头拴在哪里?谁也说不清。地锁纹的答案是把绳的另一头拴在地上:打桩锁地,铁索拴脚,它再想追,桩外的世界与它无关——越界一步,链子绷直,拽回来还带八点账。这篇把整套模块拆开:配置表、打桩结算、界距判定、拽回清算、定时器、调试按钮,一段一段照抄能跑。
一、效果演示:拴它的桩在地上,越界就拽回
演示场怪照常压向你。点「锁地!」:一根木桩砸进它脚下的地里,一道淡金的界圈绕桩铺开——九十步为界,十二秒锁期。链子从桩上绷到它脚踝,它照常朝你走,走到界圈边上——链子绷直,"拽-8"的字砸出,整个怪被硬生生拖回界内,尘土都拽起来一蓬。它再试,再拽。十二秒里它就在界圈边上反复横跳,你站在圈外安心点它的名。演示里试两笔账:锁在圈里的它的有效输出和自由追猎的输出——被拴住的怪,大半时间在跟链子较劲。地锁纹教的是画牢:追不上你的怪,让它追不到你的代价是自己撞墙。
fx-groundleash
二、底层原理:一根地桩构件加一次界距判定
模块的机关是一对搭档。地桩构件:锁地那一拍一根桩砸进它脚下——桩是绳的另一头,从这一拍起它的活动半径以桩为圆心。界距判定:每一拍量它的脚到桩的距离——九十步内自由活动,一步越界链子当场绷直,硬拽回界内还捎带八点账。和嘲讽类机制的分野在"地锁锁的是腿不是心":嘲讽改它的仇恨让它主动扑你,地锁不改仇恨只改它的活动半径——它心里还想追你,腿被桩锁死,一只心有余而腿不足的怪比晕倒的怪更让玩家有安全感。
界距为什么是九十步而不是三十步?三十步的桩等于把怪钉死在原地,铁索变成了第二根定身术;九十步刚好是"它够得着界内的你、够不着界外的世界"——锁要锁得它还能打,只是打不着界外的人。
三、核心代码:完整模块(上·骨架)
-- @file GroundLeash.lua
-- 地锁桩纹 —— 拴它的桩在地上,越界就拽回
local GroundLeash = {}
local CONST = {
LOCK_LIFE = 12.0,
LOCK_CD = 6.0,
LEASH_RANGE = 90,
SNAP_DMG = 8,
COLOR_LEASH = "#a08858",
COLOR_DEEP = "#483818",
COLOR_GHOST = "#f0e0b0",
ZORDER_LEASH = 89,
ZORDER_FX = 135,
AUTOINC_BASE = 1115000,
}
local _lockT = 0
local _cdLeft = 0
local _stakeX = 0
local _tid = 0
local _lockFx = nil
local _scheduler = nil
local _autoInc = 0
local function GenID(prefix)
_autoInc = _autoInc + 1
return string.format("%s_%d", prefix or "GLH",
CONST.AUTOINC_BASE + _autoInc)
end
local function GetActorPos(id)
if not id then return nil end
local x = SL:GetValue("ACTOR_POSITION_X", id)
local y = SL:GetValue("ACTOR_POSITION_Y", 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
function GroundLeash.Over()
local tp = GetActorPos(_tid)
if not tp then return false end
return math.abs(tp.x - _stakeX) > CONST.LEASH_RANGE
end
四、核心代码:完整模块(下·界距判定与拽回清算)
-- 界距判定与拽回清算:每拍量距,越界即拽
if not _scheduler then
_scheduler = SL:Schedule(function(dt)
_cdLeft = math.max(0, _cdLeft - dt)
if _lockT > 0 then
_lockT = _lockT - dt
if GroundLeash.Over() then
local tp = GetActorPos(_tid)
local side = (tp.x > _stakeX) and 1 or -1
SL:SetPosition(_tid,
_stakeX + side * CONST.LEASH_RANGE)
SL:ActorHurt(_tid, CONST.SNAP_DMG)
SL:TipAbove(_tid, "拽-" .. CONST.SNAP_DMG)
SL:PlaySnapFx(_tid)
ShowTip("拽回来了——链子绷直了就收")
end
if _lockT <= 0 then
SafeRemove(_lockFx)
ShowTip("桩拔了——它自由了")
end
end
end, 0.02)
end
function GroundLeash.Cast()
if _cdLeft > 0 or _lockT > 0 then return end
local tid = SL:GetValue("MARK_TARGET_ID")
local tp = tid and GetActorPos(tid)
if not tid or not tp then return end
_cdLeft = CONST.LOCK_CD
_lockT = CONST.LOCK_LIFE
_stakeX = tp.x
_tid = tid
SafeRemove(_lockFx)
_lockFx = GUI:Layout_Create(GUI:Attach_Scene(),
GenID("Stake"), _stakeX, tp.y, 0, 0, false)
GUI:setLocalZOrder(_lockFx, CONST.ZORDER_LEASH)
SL:PlayStakeDownFx(_stakeX)
ShowTip("桩打下去了——九十步为界,越界就拽")
end
SL:ScheduleOnce(function()
SL:BindDebugButton("锁地", function()
GroundLeash.Cast()
end)
ShowTip("技能已加载: 地锁纹 (调试按钮触发)")
end, 1.0)
function GroundLeash.Unload()
if _scheduler then SL:Unschedule(_scheduler) end
SafeRemove(_lockFx)
_lockT = 0
_tid = 0
end
return GroundLeash
五、机制问答
问:它站着不动锁还有意义吗?
答:有——锁拴的是活动半径不是动作,它站桩你照打,它想逃想追都得先问过链子。
问:拽回的八点血能触发击杀吗?
答:能——拽回走的是真实扣血,链子勒死最后一滴血也算你的账,勒死的怪掉落照常。
问:它被别的玩家引出界算越界吗?
答:算——界认距离不认原因,谁把它引出去,链子都照拽不误,这也是地锁保护队友的原理。
问:桩能被它拆吗?
答:不能——桩是地契不是物件,它没有拆桩的动作口径,十二秒锁期到了桩自己会拔。
问:两只怪挨着站一锁锁俩吗?
答:不锁——桩只认打桩那一刻的目标,另一只是编外的自由身,想全拴得一只一根桩。
六、调参指南与商业服怎么用
第四笔是界距的半径:九十步是"圈里打得着、圈外跑得掉"的分寸——半径太小铁索变定身,太大锁了等于没锁,九十步刚好罩住交手又放生逃亡。第三笔是拽回的账:八点对它九百的血是"疼一下不伤命"的罚金——罚太重越界成了送血包,太轻它义无反顾地撞链子,八点是"撞一次掂量一次"的价位。第二笔是打桩的时机:桩落在它脚下是默认——落在别处的桩它一步就出了界,第一拍锁期全在拽,打桩即锁脚是这套纹的手感。第一笔是链子的存在感:虚线链要一直绷在桩和脚踝之间——链子是这套纹的戏台,看不见链子的锁等于没有锁。常见坑三个:拽回判定每帧触发把怪按在界线上抖;怪死亡后链子还拴在尸体上;界圈和链子的图层盖住了怪的脚。
商业服里地锁纹是"桩子营"的家什:别人的控制靠手,他的控制靠桩——商城里桩和链的样式做成品级,木桩铁索、石桩金索、龙筋索,那根砸进地里的桩和绷直的虚线链就是桩子营的门闩。运营落地还有两笔:一段是画圈教学——教一句"桩打在它脚下,圈外的世界它爱莫能助",流派第一课是选地方下桩;一段是桩王榜——按锁期内拽回的总次数排名,桩打得最准的人有碑。变体做成双桩锁:两只怪各拴一根桩互为半径——从单桩到连环桩,桩子营的桩越打越密。这一篇的演示和整套模块照抄能跑,改的就是 CONST 那张表。
写完留一句给做位移约束系的同学:地锁纹卖的是"绳的那头拴在地上"——那根砸进土里的桩和绷直就收的链子,是把追猎半径写进地契的一根门闩。
全站技术干货持续更新:996 引擎 / Lua 实战帖,语法、参数与示例一篇讲透。进入文章地图 · 查看全部 →
接手二开的兄弟几乎都撞过同一堵墙:玩家嫌走路"一格一格像机器人",老板拍板要"丝滑移动",改服务端速度?不对。改客户端动画帧…
【游戏功能】 先看一个熟场面:法师的火球特效挂在怪的脚后跟上,明明技能说明写着"焚烧其面",火星子却在地上打滚。群里有位策划…
【游戏功能】 上周有个开服的老板在群里发了一段录屏:他的战士明明刀刀都砍中了,观众却一片"这刀挥空了吧"。他原话是"判定日志…
【游戏功能】 先说结论放在开头:怪的皮一会儿绿一会儿红,不是美术换了几套贴图,是染色系统在怪身上盖了一层"色镜"。开服群里有…
前两天群里有个架设的朋友问了个需求:中毒的人要变绿、每两秒掉一次血、毒还能叠五层,问是不是要在服务端把整套状态机重写。我说你…
【游戏功能】 先抛一个坑:五口钟一模一样大,为什么一口比一口疼?先后次序动不得吗?倒过来敲会怎样?这篇把编钟纹整套写法拆开:…