From e6bb957d3d8437986a92cde1c202d4d669cc8514 Mon Sep 17 00:00:00 2001 From: Lenheart <947330670@qq.com> Date: Fri, 10 Apr 2026 00:54:37 +0800 Subject: [PATCH] =?UTF-8?q?feat(Steal):=20=E6=B7=BB=E5=8A=A0=E8=A7=A3?= =?UTF-8?q?=E9=94=81=E6=88=90=E5=8A=9F=E5=8A=A8=E7=94=BB=E5=92=8C=E9=9F=B3?= =?UTF-8?q?=E6=95=88=E5=8F=8D=E9=A6=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 将密码框滚动速度从500ms调整为250ms提升用户体验 - 添加解锁成功动画序列和音效反馈 - 增加全部解锁后的处理逻辑和动画播放 - 优化宝箱动画显示比例 - 添加解锁失败音效提示 --- Project/Steal/Steal.nut | 133 +++++++++++++++++++++++++++++++++++++--- 1 file changed, 123 insertions(+), 10 deletions(-) diff --git a/Project/Steal/Steal.nut b/Project/Steal/Steal.nut index 3a2436c..225bcd4 100644 --- a/Project/Steal/Steal.nut +++ b/Project/Steal/Steal.nut @@ -12,7 +12,7 @@ class StealC_Password_Box extends LenheartNewUI_CommonUi { ScrollBaseIndex = 0; InitBaseIndex = 0; ScrollStartTimeMs = 0; - RowDurationMs = 500; + RowDurationMs = 250; RowHeight = 24; ColumnYOffset = 0; CorrectIndex = 0; @@ -31,7 +31,7 @@ class StealC_Password_Box extends LenheartNewUI_CommonUi { ColumnYOffset = -(PhaseIndex * 8); NumberSeq = []; - for (local i = 0; i < 10; i++) { + for (local i = 0; i< 10; i++) { local Info = { num = PassStr[sq_getRandom(0, PassStr.len() - 1)], CorrectFlag = false, @@ -45,7 +45,7 @@ class StealC_Password_Box extends LenheartNewUI_CommonUi { local SeqLen = NumberSeq.len(); if (SeqLen > 0) { local Phase = PhaseIndex % SeqLen; - if (Phase < 0) { + if (Phase< 0) { Phase += SeqLen; } ScrollBaseIndex = Phase; @@ -60,7 +60,7 @@ class StealC_Password_Box extends LenheartNewUI_CommonUi { return 0; } local Value = Index % SeqLen; - if (Value < 0) { + if (Value< 0) { Value += SeqLen; } return Value; @@ -71,7 +71,7 @@ class StealC_Password_Box extends LenheartNewUI_CommonUi { RowDurationMs = 1; } local RunTimeMs = Clock() - ScrollStartTimeMs; - if (RunTimeMs < 0) { + if (RunTimeMs< 0) { RunTimeMs = 0; } local PassedRows = (RunTimeMs / RowDurationMs).tointeger(); @@ -94,7 +94,7 @@ class StealC_Password_Box extends LenheartNewUI_CommonUi { for (local k = -2; k <= 2; k++) { local CY = BaseY + (k * CycleHeight); local Dist = abs(CY - RefY); - if (Dist < BestDist) { + if (Dist< BestDist) { BestY = CY; BestDist = Dist; } @@ -132,7 +132,7 @@ class StealC_Password_Box extends LenheartNewUI_CommonUi { local DrawCount = (Height / RowHeight).tointeger() + 4; local TextY = Y + 10; - for (local i = -2; i < DrawCount - 2; i++) { + for (local i = -2; i< DrawCount - 2; i++) { local Info = NumberSeq[GetLoopIndex(ScrollBaseIndex + i)]; local NumStr = Info.num.tostring(); local Color = Info.CorrectFlag ? sq_RGBA(157, 245, 10, 255) : sq_RGBA(150, 150, 150, 255); @@ -161,9 +161,17 @@ class StealC extends LenheartNewUI_Windows { CorrectLockedCount = 0; LockBoxHeight = 24; LockSnapOffsetY = -6; + AllUnlockedTriggered = false; + AniQueue = null; + UnlockSuccessAni = null; + UnlockAniPlaying = false; + UnlockAniFinished = false; + UnlockFinalizeDone = false; + UnlockAniFrameDelay = 60; constructor(gObjectId, gX, gY, gWidth, gHeight, gTitleH) { Childrens = []; + AniQueue = QuestQueue(); //注册控件 RegisterWidget(); @@ -219,6 +227,97 @@ class StealC extends LenheartNewUI_Windows { UnlockComplete = CorrectLockedCount.tofloat() / Total.tofloat(); } + function BuildUnlockFrameArr() { + local FrameArr = []; + local Delay = UnlockAniFrameDelay; + if (Delay <= 0) { + Delay = 60; + } + for (local i = 0; i< 13; i++) { + FrameArr.append({ + ImgIndex = i, + Delay = Delay, + Pos = [0, 0] + }); + } + return FrameArr; + } + + function StartUnlockSuccessSequence() { + if (UnlockAniPlaying || UnlockAniFinished) { + return; + } + + local FrameArr = BuildUnlockFrameArr(); + UnlockSuccessAni = Lenheart_Ani("", FrameArr, [X + 269, Y + 260]); + UnlockSuccessAni.ImgPath = "steal/unlock.img"; + UnlockSuccessAni.LoopFlag = false; + UnlockSuccessAni.Reset(); + + UnlockAniPlaying = true; + UnlockAniFinished = false; + if (AniQueue) { + AniQueue.RemoveQuest("StealUnlockSuccessAni"); + AniQueue.AddQuest("StealUnlockSuccessAni", function(Name, Time) { + if (!UnlockSuccessAni) { + UnlockAniPlaying = false; + UnlockAniFinished = true; + AniQueue.RemoveQuest(Name); + FinalizeUnlockSuccess(); + return; + } + UnlockSuccessAni.X = X + 324; + UnlockSuccessAni.Y = Y + 109; + UnlockSuccessAni.Show(Duration); + if (UnlockSuccessAni.State == 0) { + UnlockAniPlaying = false; + UnlockAniFinished = true; + AniQueue.RemoveQuest(Name); + FinalizeUnlockSuccess(); + } + }.bindenv(this)); + } else { + UnlockAniPlaying = false; + UnlockAniFinished = true; + FinalizeUnlockSuccess(); + } + } + + function FinalizeUnlockSuccess() { + if (UnlockFinalizeDone) { + return; + } + UnlockFinalizeDone = true; + SendStealUnlockPack(); + CloseWindow(); + Visible = false; + } + + function SendStealUnlockPack() { + // TODO: fill op and fields when server protocol is finalized. + // SendPackEx({ op = xxxx }); + } + + function OnAllUnlockedInternal() { + R_Utils.PlaySound("GAMBLE_RESULT_GOOD"); + print("Steal all unlocked: " + CorrectLockedCount); + StartUnlockSuccessSequence(); + } + + function CheckAllUnlocked() { + if (AllUnlockedTriggered) { + return; + } + local Total = GetPasswordBoxTotal(); + if (Total <= 0) { + return; + } + if (CorrectLockedCount >= Total) { + AllUnlockedTriggered = true; + OnAllUnlockedInternal(); + } + } + function CheckSpaceLock() { if (!Visible) { return; @@ -231,8 +330,12 @@ class StealC extends LenheartNewUI_Windows { return; } if (FocusBox.TryLockByRect(GetLockTopY(), LockBoxHeight, LockSnapOffsetY)) { + R_Utils.PlaySound("TRADE_OK"); CorrectLockedCount += 1; RefreshUnlockComplete(); + CheckAllUnlocked(); + } else { + R_Utils.PlaySound("ALERT_2"); } } @@ -242,7 +345,13 @@ class StealC extends LenheartNewUI_Windows { //宝箱动画 local Ani = DrawAniEx(X + 425, Y + 230, "npc/animation/storagediamond.ani"); - Ani.setImageRateFromOriginal(2.0, 2.0); + Ani.setImageRateFromOriginal(1.7, 1.7); + //如果未解锁 + if (UnlockComplete< 1.0) { + //宝箱锁图像 + Img.DrawPng(12, X + 335, Y + 120); + } + //完成度文字 @@ -264,6 +373,9 @@ class StealC extends LenheartNewUI_Windows { function Show(obj) { DrawMain(obj); + if (AniQueue) { + AniQueue.Run(); + } //裁切遮罩密码框 setClip(X + 280, Y + 268, X + 280 + 8 * 30, Y + 268 + 120); @@ -290,12 +402,13 @@ getroottable().rawdelete("L_Each_Obj"); + function Lenheart_Steal_Fun(obj) { local RootTab = getroottable(); if (!RootTab.rawin("Steal_Obj")) { RootTab.rawset("Steal_Obj", true); - LenheartNewUI_CreateWindow(StealC, "偷窃系统窗口", 0, 0, 800, 600, 0); + LenheartNewUI_CreateWindow(StealC, "Steal_Window", 0, 0, 800, 600, 0); } } -getroottable()["LenheartFuncTab"].rawset("StealFuncN", Lenheart_Steal_Fun); +getroottable()["LenheartFuncTab"].rawset("StealFuncN", Lenheart_Steal_Fun); \ No newline at end of file