CHUAN2 DEV ENGINE
996 正版授权研发中心 · 360 授权合作教学中心 · 抖音传奇直播合作授权 · 快手推广运营商授权
OFFICIAL LICENSED ACADEMY 查验官方授权证书 →
// 威海旷世互娱教学基地 · 技术文章
进阶实战游戏功能996引擎

兑票当纹:挨的刀换成票,票票能兑现

2026-10-02 00:24 作者:996 技术组 996引擎Lua教程传奇脚本进阶实战游戏功能996引擎

【游戏功能】

tk=math.min(3,tk+1)——先拆这一行。兑票纹的账本全在这一行的封顶里:它每打你一爪,你兜里就多一张票,但票夹只有三格——取小函数把票数钉死在三,第四张票当场作废。兑票纹的账是当铺的账:挨的刀不是白挨的,每一爪换来一张当票,票攥在手里随你挑——兑成奶,一票顶六点血;兑成刀,一票顶八点的劈头。这篇把整套模块拆开:配置表、收票结算、封顶票夹、双通兑现、定时器、调试按钮,一段一段照抄能跑。

一、效果演示:挨的刀换成票,票票能兑现

演示场怪照常抡爪。点「兑奶!」和「兑刀!」两枚按钮分列左右——兑票期里你兜里的票随挨打攒:它一爪十四点砸下来,你掉血的同一拍,"票+1"的纸片从身上飘出,票夹三格一格格填上。票满三张,两条路随你挑:点兑奶,十八点的绿字落袋,血条回一口;点兑刀,二十四点的金字劈在怪脸上。演示里试两笔账:兑票流的挨打总量换回的奶和刀,与硬扛不带票的总账——同样的挨打,带票的把疼换成了本钱。兑票纹教的是兑现:疼不是白疼的,票在手里,怎么花你说了算——花在刀口上还是花在血条上,都是你的主意。

demo
 fx-ticketpay

二、底层原理:一次收票结算加一柜双通兑现

模块的机关是一对搭档。收票结算:它打你的每一爪在掉血的同一拍出一张票——票认挨打不认时间,站一整天不打仗票夹也是空的。双通兑现:票在柜上随你挑两个通——奶通一票六点、刀通一票八点,兑完清票,票夹腾格子接着收。和反击类机制的分野在"兑票的选择权攥在玩家手里":反伤是挨了自动还,兑票是挨了攒着、挑着、选着兑现——同样的疼,兑成续命还是兑成伤人,这一票的主权归玩家手里攥着,谁也抢不走,这份主权就是兑票纹全部的体面。

票夹为什么封顶三张?不封顶的版本票无限攒,玩家把票留到决战一波兑现,攒票变成闷声的蓄力;三张封顶逼着玩家"到账就花"——票是流通券不是存款,当铺的规矩是柜上不过夜——规矩立住了,票才值钱,值钱的票才有人愿意挨打去攒。

三、核心代码:完整模块(上·骨架)

lua
-- @file TicketPay.lua
-- 兑票当纹 —— 挨的刀换成票,票票能兑现

local TicketPay = {}

local CONST = {
    CREST_LIFE    = 14.0,
    CREST_CD      = 4.0,
    TICKET_CAP    = 3,
    HEAL_PER      = 6,
    STRIKE_PER    = 8,

    COLOR_TICKET  = "#c09868",
    COLOR_DEEP    = "#483018",
    COLOR_GHOST   = "#f0e0c0",

    ZORDER_TICKET = 133,
    ZORDER_FX     = 135,
    AUTOINC_BASE  = 1129000,
}

local _crestT    = 0
local _cdLeft    = 0
local _tickets   = 0
local _crestFx   = nil
local _scheduler = nil
local _autoInc   = 0

local function GenID(prefix)
    _autoInc = _autoInc + 1
    return string.format("%s_%d", prefix or "TKP",
        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 TicketPay.Tickets()
    return _tickets
end

四、核心代码:完整模块(下·收票与双通兑现)

lua
-- 收票结算:它打你的每一爪出一张票
SL:RegisterLUAEvent(LUA_EVENT_HURT_TAKEN, "TKP_Print", function(dmg)
    if _crestT <= 0 or dmg <= 0 then return dmg end
    if _tickets < CONST.TICKET_CAP then
        _tickets = _tickets + 1
        SL:TipAboveMe("票+1")
    end
    return dmg
end)

-- 兑奶:一票六点,兑完清夹
function TicketPay.RedeemHeal()
    if _tickets <= 0 then
        ShowTip("兜里没票——先挨两爪")
        return
    end
    local heal = _tickets * CONST.HEAL_PER
    local myID = SL:GetValue("USER_ID")
    SL:HealActor(myID, heal)
    SL:TipAboveMe("+" .. heal)
    _tickets = 0
    ShowTip("兑了奶——" .. heal .. "点入账")
end

-- 兑刀:一票八点,劈头清夹
function TicketPay.RedeemStrike(tid)
    if _tickets <= 0 then
        ShowTip("兜里没票——先挨两爪")
        return
    end
    local strike = _tickets * CONST.STRIKE_PER
    SL:ActorHurt(tid, strike)
    SL:TipAbove(tid, "兑刀-" .. strike)
    _tickets = 0
    ShowTip("兑了刀——" .. strike .. "点劈它脸上")
end

function TicketPay.Cast()
    if _cdLeft > 0 or _crestT > 0 then return end
    local myID = SL:GetValue("USER_ID")
    _cdLeft = CONST.CREST_CD
    _crestT = CONST.CREST_LIFE
    _tickets = 0
    SafeRemove(_crestFx)
    _crestFx = GUI:Layout_Create(GUI:Attach_SceneF(),
        GenID("Book"), 0, 0, 0, 0, false)
    GUI:setLocalZOrder(_crestFx, CONST.ZORDER_TICKET)
    SL:PlayBookUpFx(myID)
    ShowTip("当铺开了——挨打攒票,兑奶兑刀随你挑")
end

-- 定时器:纹成倒计时与柜期清收
if not _scheduler then
    _scheduler = SL:Schedule(function(dt)
        _cdLeft = math.max(0, _cdLeft - dt)
        if _crestT > 0 then
            _crestT = _crestT - dt
            if _crestT <= 0 then
                SafeRemove(_crestFx)
                ShowTip("纹收了——手里的票作废了")
            end
        end
    end, 0.02)
end

SL:ScheduleOnce(function()
    SL:BindDebugButton("兑奶", function()
        TicketPay.RedeemHeal()
    end)
    SL:BindDebugButton("兑刀", function(tid)
        TicketPay.RedeemStrike(
            SL:GetValue("MARK_TARGET_ID"))
    end)
    ShowTip("技能已加载: 兑票纹 (调试按钮触发)")
end, 1.0)

function TicketPay.Unload()
    if _scheduler then SL:Unschedule(_scheduler) end
    SafeRemove(_crestFx)
    _crestT = 0
    _tickets = 0
end

return TicketPay

五、机制问答

问:票能跨场攒着吗?
答:不能——票随纹开随纹清,柜期一过手里的票全作废,当铺不留过夜的客。

问:满票时再挨一爪票归谁?
答:归风——票夹满格新票作废,这也逼着玩家别死攥着票不花,柜上不过夜的规矩两头管。

问:兑刀的那一下吃暴击吗?
答:吃——兑刀走独立的重击通道,暴击照掷,三票兑出个暴击是当铺的开张红。

问:血满的时候兑奶亏吗?
答:亏——满血兑奶的票就地蒸发,兑之前掂量血条,当铺概不退换。

问:它不打我票从哪来?
答:不来——票认挨打不认时间,它客气你兜里就干净,想攒票先得站到刀口上去。

六、调参指南与商业服怎么用

第四笔是票夹的封顶:三格的柜面是那行取小的作用——不封顶的版本票变存款,封顶太紧一爪一票刚攒就满,三格刚好是"攒得起也花得急"的柜面。第三笔是两通的汇率:奶票六点刀票八点是"伤人略贵于续命"的汇率——汇率倒挂人人兑奶变奶妈,拉平了选择失去意义,刀略贵才逼人在保命和伤人之间真挑一回。第二笔是收票的口径:认挨打不认时间是当票的出身——把时间也计票的版本站着不动也进账,票就没了血汗的味道。第一笔是纸票的演出:纸片从身上飘出、票夹三格填格子——票是这套纹的实体账,看不见票的兑现是一笔糊涂账。常见坑三个:票夹封顶后收票结算没闸导致票数穿模;兑奶在血满时白兑没有提示;纸票演出在兑完后没散场飘着旧票。

商业服里兑票纹是"当铺行"的柜面:别人把挨打记成仇,他把挨打记成票——商城里票的样式做成品级,草纸票、绢票、鎏金当票,那三格填满的票夹就是当铺行的柜台。运营落地还有两笔:一段是守柜教学——教一句"票到三张就花,柜上不过夜",流派第一课是流通;一段是当官榜——按兑票期的总兑现价值排名,票花得最活的人有碑。变体做成利票:满三张后再挨一爪,旧票升值一点——从死封顶到活升值,当铺行的柜台越办越活。这一篇的演示和整套模块照抄能跑,改的就是 CONST 那张表。

写完留一句给做兑换系的同学:兑票纹卖的是"疼可以攒着花"——那三格填满的票夹和随你挑的两个兑现口,是把挨打从损耗改成流通券的第一面柜栅。

作者履历与出处

本文由 996 技术组基于 996 引擎官方知识库与浮生梦老师课程体系整理。团队长期从事传奇类引擎 Lua 后端逻辑、客户端界面与商业版本交付,内容以官方知识库与真实项目为出处,按版本持续修订。

← 返回文章地图返回研学路径

幂尔框架 · 实战干货 · 接口调用

LATEST ARTICLES

全站技术干货持续更新:996 引擎 / Lua 实战帖,语法、参数与示例一篇讲透。进入文章地图 · 查看全部 →

进阶实战游戏功能

Lua自动炮台:架一个自动索敌开火

【语法算法】 上一版的炮台索敌逻辑有个隐蔽报错:炮台永远打同一个怪——即使那只怪已经死了,索敌的游标也不挪窝。追到底索敌的游…

2026-10-02 04:50 996 技术组
进阶实战游戏功能

Lua元素转换:火伤转冰伤附带减速

【语法算法】 先抛一个坑:打不完的火系怪怎么办?火抗怪火打不动,换冰系技能要切装备要换面板——切完黄花菜都凉了。元素转换的答…

2026-10-02 04:50 996 技术组
进阶实战游戏功能

Lua连锁引燃:一个着火引燃下一个

【语法算法】 上个月的事故复盘会上有个数字被念了三遍:四成——策划写的是"同伴陪疼四成",代码落下去成了"陪疼四十点",两只…

2026-10-02 04:50 996 技术组
进阶实战游戏功能

Lua弹射地垫:踩上去弹飞到空中

【语法算法】 单行代码拆解:弹射初速=-420——弹射的全部动力就这一行的负初速。负号朝上、四百二十是弹射的初速大小——踩上…

2026-10-02 04:50 996 技术组
进阶实战游戏功能

Lua时间减缓:流速减半的局部时差

【语法算法】 上一版的减速类模块全按"乘以零点五"来写,帧率无关的版本照搬了这套写法——结果高帧率机上减速效果好,低帧率机上…

2026-10-02 04:50 996 技术组
进阶实战游戏功能

Lua引力球:丢出去把怪吸过来

【语法算法】 先抛一个坑:怎么把散在四处的怪聚到一起打?逐个拉是笨办法,一个范围技又只能打一片——引力球的答案是一个会动的吸…

2026-10-02 04:50 996 技术组