【游戏功能】
bn.t = bn.t - dt——一行旗面倒计时的代码,撑起了破军旗全部的紧迫感:旗立三秒、圈内加攻三成,旗倒的那一帧加成散得干干净净——立旗的时机就是这门机制的全部操作。这篇的核心代码照引擎技能脚本的全规格写:配置表、旗面构件、圈内判定、定时器、调试按钮。
一、效果演示:旗立三秒,圈内加成
演示场点「立旗!」:一面金色的旗帜落在你和怪的正中间——旗面虚线圈开、头顶挂"破军 三秒"。你站在旗内:普攻从十二涨到十五,金色刀光加宽;怪冲进旗内照样挨打——旗不偏袒任何一方,圈内双方都受影响。三秒一到旗面当场散掉,加成同步消失。演示里试两个站位:圈内站桩打——加成的十二变十五刀刀金色;圈外远站——刀刀灰字白给。站位的差别就是这门机制的教学。
fx-warbanner
二、底层原理:一面旗加一个圈域加成
模块的机关是一对搭档。旗面态:旗立期间 _fieldT 大于零,圈的半径六十步、纵横比零点三六压扁贴地。圈内判定:玩家的横坐标离旗心不超过六十步即算在圈内——判定每帧跑,出圈的瞬间加成即断。加成侧不走独立加持,而是直接改写下一刀的伤害系数——SetNextAttackAmp 每帧按圈内判定重设,进出圈的加成切换就在一帧内完成。旗面倒了加成同步清——加成和旗面同帧同生同死,不存在旗倒了加成还挂着的残账。旗面倒了加成同步清——加成和旗面同帧同生同死,不存在旗倒了加成还挂着的残账。旗面的倒计时要一直挂着——旗倒前三秒的读秒写在旗面上方,读秒越近圈沿的虚线闪得越急,闪急了玩家就知道该撤了。
三、核心代码:完整模块(上·骨架)
-- @file WarBanner.lua
-- 破军旗 —— 旗立三秒圈内加攻,旗倒攻散
local WarBanner = {}
local CONST = {
BANNER_LIFE = 3.0,
BANNER_CD = 8.0,
BANNER_R = 60,
IN_AMP = 1.3,
COLOR_BANNER = "#d8b34a",
COLOR_DEEP = "#6b5a2b",
COLOR_GHOST = "#f5ecc8",
ZORDER_BANNER = 128,
ZORDER_FX = 135,
AUTOINC_BASE = 976000,
}
local _bannerT = 0
local _bannerX = 0
local _cdLeft = 0
local _scheduler = nil
local _autoInc = 0
local function GenID(prefix)
_autoInc = _autoInc + 1
return string.format("%s_%d", prefix or "WBN",
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
local function CreateBannerNode(x)
local node = GUI:Layout_Create(GUI:Attach_SceneF(),
GenID("Bnr"), x, 0, 0, 0, false)
GUI:setLocalZOrder(node, CONST.ZORDER_BANNER)
GUI:DrawLine_Create(node, "pole", 0, 0, 6,
-3, 0, -3, -70, CONST.COLOR_BANNER, 240)
GUI:DrawLine_Create(node, "flag", 0, 0, 8,
-3, -70, 22, -62, CONST.COLOR_GHOST, 240)
return node
end
四、核心代码:完整模块(下·定时器与圈内判定)
-- 立旗
function WarBanner.Cast()
if _cdLeft > 0 or _bannerT > 0 then return end
_cdLeft = CONST.BANNER_CD
_bannerT = CONST.BANNER_LIFE
local mp = GetActorPos(SL:GetValue("USER_ID"))
local tp = GetActorPos(SL:GetValue("MARK_TARGET_ID"))
if mp and tp then
_bannerX = (mp.x + tp.x) / 2
end
CreateBannerNode(_bannerX)
ShowTip("旗立了——三秒圈内加三成,抢位")
end
-- 圈内判定
local function InBanner(x)
if _bannerT <= 0 then return false end
return math.abs(x - _bannerX) <= CONST.BANNER_R
end
-- 定时器
if not _scheduler then
_scheduler = SL:Schedule(function(dt)
_cdLeft = math.max(0, _cdLeft - dt)
if _bannerT <= 0 then return end
_bannerT = _bannerT - dt
if _bannerT <= 0 then
ShowTip("旗倒了——加成散了")
end
local myID = SL:GetValue("USER_ID")
local mp = GetActorPos(myID)
if mp then
SL:SetNextAttackAmp(
InBanner(mp.x) and CONST.IN_AMP or 1.0)
end
end, 0.02)
end
SL:RegisterLUAEvent(LUA_EVENT_SCENE_CLEAR, "WBN_Clear", function()
_bannerT = 0
SL:SetNextAttackAmp(1.0)
end)
SL:ScheduleOnce(function()
ShowTip("技能已加载: 破军旗 (调试按钮触发)")
end, 1.0)
return WarBanner
下半场的加成出口走 SetNextAttackAmp 每帧重设——出圈的瞬间加成即断、进圈的瞬间加成即挂,一帧都不多。旗面到期时加成一起清——场景清空钩子兜底重置,下一场从干净状态起步。
五、调参指南与商业服怎么用
调参三笔账。圈内加成三成对旗寿三秒是"三秒的狂欢"——加成过五成圈内输出碾压圈外,机制变成"进圈挂机";低于两成圈内圈外没区别,旗变装饰。旗寿三秒对冷却八秒留五秒真空——真空里裸打,真空越短旗越像常驻。旗半径六十步对怪的攻击距离三十步是"能站两人"的圈子——圈子太大怪也进来白嫖加成。常见坑三个:出圈后加成没断下一刀还是乘一三;旗面的虚线圈视觉和实际判定圈不同大小;旗立期间怪的攻击也加成——旗不该偏袒怪。
商业服里破军旗是"阵地流派"的入门课:旗的位置就是输出循环的上半段——圈内的三秒狂欢逼玩家在怪的攻击间隙里抢位立旗。攻城战里它是推进的信号——旗立在哪个路口,哪条路就是集火点。变体做成破军连旗:旗倒后下一面旗的加成叠加——连环立旗的收益翻着翻地涨。这一篇的演示和整套模块照抄能跑,改的就是 CONST 那张表。
写完留一句做阵地系的同学:破军旗卖的是"三秒的决心"——旗立在怪的刀口下,敢抢位的玩家才配拿那三成。旗立在怪的刀口下,敢抢位的玩家才配拿那三成。旗面的位置也有讲究——立在怪的撤退路线上,怪的退路被旗封住,进退两难的怪只能硬吃旗内加成的一刀。
旗面的收缩也要做——旗的圈从六十步开始慢慢收缩、缩到四十步才散——缩圈的旗逼着怪和你贴身,缩到头就是贴身肉搏。旗的收缩速度也是节奏的一环——匀速收缩的旗给玩家一个稳定的抢位窗口,忽快忽慢的旗会让玩家不知道该什么时候进。旗面和怪的交叉也值得做——先立旗加成、再缩地阵把怪压进旗内,两个圈的叠加就是阵地战的终极形态。破军旗和连招谱的交叉也值得做——按谱出招的每一招都算一次拍,谱和拍合流就是阵地战的高级课。旗面的虚线圈也做了双向的视觉——旗内的单位头顶亮金色小三角、旗外的没有——三角形的有无就是圈内圈外的视觉标尺。旗面的碰撞判定也别忘了做——怪的碰撞盒和旗的判定圈的交叠就是进圈的判据,两个圆的交叉判定比点到点的距离判定更宽容。旗面的收缩也要做——旗的圈从六十步开始慢慢收缩、缩到四十步才散——缩圈的旗逼着怪和你贴身,缩到头就是贴身肉搏。旗的收缩速度也是节奏的一环——匀速收缩的旗给玩家一个稳定的抢位窗口,忽快忽慢的旗会让玩家不知道该什么时候进。旗面和怪的交叉也值得做——先立旗加成、再缩地阵把怪压进旗内,两个圈的叠加就是阵地战的终极形态。破军旗和连招谱的交叉也值得做——按谱出招的每一招都算一次拍,谱和拍合流就是阵地战的高级课。
全站技术干货持续更新:996 引擎 / Lua 实战帖,语法、参数与示例一篇讲透。进入文章地图 · 查看全部 →
【游戏功能】 蓄力技为什么总是单发?影炮偏要贯穿全屏:蓄一秒射一道暗影弹道穿全屏——线上所有目标各挨五十五,弹道从你脚下贯穿…
【游戏功能】 灼烧为什么总烧在皮肤上?灼心偏要烧进心里:心被灼了六秒——六秒里怪每出一招就自损八,出得越多损得越多。这篇的核…
【游戏功能】 魂卫为什么只有三盏就不能多了?魂蜂偏要做成可以积累的:杀掉小怪化一盏魂蜂跟着你走,至多三盏——三盏魂蜂各自两秒…
【游戏功能】 镜墙为什么只能反弹不能冰冻?霜镜偏要双管齐下:弹道撞上霜镜原路画回去——回程的弹道还带着冰冻效果,扎中怪怪也冻…
【游戏功能】 单体射击为什么打不动厚血怪?穿心刺给的答案是:箭伤八加穿心伤,穿心伤等于最大血量百分之六——血越厚的怪越疼。这…
【游戏功能】 影刺的全机制就一句话:化影绕到它身后,从背刺出的那一刀双倍二十四——正面十二、背后二十四,它一转身就变白板。这…