From baf1620a358755b082c9cffaa7c9465971c30040 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=A3=AE2003?= <2384017988@qq.com> Date: Sun, 19 Jul 2026 17:39:31 +0800 Subject: [PATCH] 1 --- .../Scripts/Manager/CreateFishManager.cs | 51 ++++++------- .../Game/DefaultDieEffect/Coin/CoinScript.cs | 29 +++++++- .../aa/UI/Game/GameMainPanel_FishBase.cs | 74 ++++++++++++++++--- 3 files changed, 109 insertions(+), 45 deletions(-) diff --git a/Assets/MyGame/Scripts/Manager/CreateFishManager.cs b/Assets/MyGame/Scripts/Manager/CreateFishManager.cs index 1ec2708a5..69881d7c8 100644 --- a/Assets/MyGame/Scripts/Manager/CreateFishManager.cs +++ b/Assets/MyGame/Scripts/Manager/CreateFishManager.cs @@ -1052,26 +1052,29 @@ public class CreateFishManager : MonoSingleton /// /// 进度条加载结束时房主调用,创建一批初始鱼(进度 0.2~0.8),让屏幕开局就有鱼不会显得空。 - /// 只在房主端调用,通过 SyncGameData 广播给其他客户端,所有客户端收到后按 time 字段计算 moveTime, - /// 自然处于路径中段。 + /// 直接复用 CreateFishManager 原有的出鱼机制: + /// - GetRandomFishByWeight 按权重选鱼(和 TickNormalFishSpawn 一致) + /// - WebSocketSendList.SyncGameData 帧同步广播(和 SendCreateFishRequest 一致) + /// - 通过 time 字段控制创建时间,让所有客户端收到后 progress 自然在 [0.2, 0.8] + /// mc.moveTime = (CurrentTimestampMs - time) / 1000f + /// progress = moveTime / times + /// → time = CurrentTimestampMs - progress * times * 1000 + /// + /// 只选普通鱼(fishTypeConfig[普通鱼]),Boss/特殊Boss/黄金鱼/特殊鱼由原有 Tick 逻辑 + /// 按时间间隔触发,不在这里批量生成,避免开局一堆 Boss。 /// /// 要创建的鱼数量 public void CreateInitialFishes(int count) { if (!fangzhu) return; - if (spawnList == null || spawnList.Count == 0) return; - if (FishDatas == null || FishDatas.Count == 0) return; + if (fishTypeConfig == null) return; + if (!fishTypeConfig.TryGetValue(FishTypeEnum.普通鱼, out var normalList) || normalList.Count == 0) return; - // 只选普通鱼(type==1),鱼阵留给正常刷怪逻辑 - var normalFishes = spawnList.Where(f => f.type == 1).ToList(); - if (normalFishes.Count == 0) return; - - int actualCount = Mathf.Min(count, normalFishes.Count * 3); // 避免极端值 - var created = new HashSet(); // 防止 guid 重复(虽然概率极低) - - for (int i = 0; i < actualCount; i++) + for (int i = 0; i < count; i++) { - var fish = normalFishes[Random.Range(0, normalFishes.Count)]; + // ⭐ 用原有的 GetRandomFishByWeight 按权重选鱼 + var fish = GetRandomFishByWeight(normalList); + if (fish == null) continue; // 从该鱼的路径列表里随机选一条 if (!FishDatas.TryGetValue(fish.fishNumber, out var ft)) continue; @@ -1079,24 +1082,11 @@ public class CreateFishManager : MonoSingleton int pathId = ft.pathList[Random.Range(0, ft.pathList.Count)]; - // ⭐ 关键:通过 time 字段控制鱼已走过的进度 - // mc.moveTime = (CurrentTimestampMs - time) / 1000f - // 想让 progress = moveTime / times ∈ [0.2, 0.8] - // → time = CurrentTimestampMs - progress * times * 1000 + // ⭐ 通过 time 字段控制创建时间,让 progress ∈ [0.2, 0.8] float progress = Random.Range(0.2f, 0.8f); - float moveTimeSec = progress * fish.times; - long timeOffsetMs = (long)(moveTimeSec * 1000f); + long timeOffsetMs = (long)(progress * fish.times * 1000f); long sendTime = BeijingTimeManager.Instance.CurrentTimestampMs - timeOffsetMs; - string guid = Guid.NewGuid().ToString(); - int safety = 0; - while (created.Contains(guid) && safety < 10) - { - guid = Guid.NewGuid().ToString(); - safety++; - } - created.Add(guid); - var sgd = new SyncGameData { sitPos = GameManager.Instance.gameData.roomJoinNotice.position, @@ -1105,15 +1095,16 @@ public class CreateFishManager : MonoSingleton frameData = new FrameData_CreateFish { fishNumber = fish.fishNumber, - guid = guid, + guid = Guid.NewGuid().ToString(), moveLineId = pathId.ToString() } }; + // ⭐ 走原有的帧同步广播链路 WebSocketSendList.SyncGameData(sgd); } - Debug.Log($"[CreateFishManager] 初始鱼已创建: {actualCount} 条 (房主广播)"); + Debug.Log($"[CreateFishManager] 初始鱼已广播: {count} 条 (房主,走原有出鱼机制)"); } #endregion diff --git a/Assets/MyGame/aa/Game/DefaultDieEffect/Coin/CoinScript.cs b/Assets/MyGame/aa/Game/DefaultDieEffect/Coin/CoinScript.cs index 6d8f904f9..33ab9f394 100644 --- a/Assets/MyGame/aa/Game/DefaultDieEffect/Coin/CoinScript.cs +++ b/Assets/MyGame/aa/Game/DefaultDieEffect/Coin/CoinScript.cs @@ -11,11 +11,32 @@ public class CoinScript : BJBase tMP_CoinCount.text = NumAdd(coinCount.ToString()); // 自己爆奖显示金,别人显示银 - bool isMine = !string.IsNullOrEmpty(userID) - && GameManager.Instance != null - && GameManager.Instance.user != null - && userID == GameManager.Instance.user.id; + bool isMine = IsLocalPlayer(); if (gold != null) gold.SetActive(isMine); if (silver != null) silver.SetActive(!isMine); } + + private bool IsLocalPlayer() + { + // 优先用 userID 判断 + if (!string.IsNullOrEmpty(userID) + && GameManager.Instance != null + && GameManager.Instance.user != null + && userID == GameManager.Instance.user.id) + return true; + + // 兜底:用 sitID 判断(boss 杀小鱼时 userID 可能为空) + if (GameManager.Instance == null || GameManager.Instance.user == null) + return false; + + var sits = CreateFishManager.Instance?.currGameType?.list_Sits; + if (sits == null) return false; + + foreach (var sit in sits) + { + if (sit != null && sit.user == GameManager.Instance.user.id) + return sitID == sit.posID; + } + return false; + } } diff --git a/Assets/MyGame/aa/UI/Game/GameMainPanel_FishBase.cs b/Assets/MyGame/aa/UI/Game/GameMainPanel_FishBase.cs index 7a277b747..84a0a6416 100644 --- a/Assets/MyGame/aa/UI/Game/GameMainPanel_FishBase.cs +++ b/Assets/MyGame/aa/UI/Game/GameMainPanel_FishBase.cs @@ -83,6 +83,7 @@ using Assets.MyGame.Scripts.Net; using Assets.MyGame.Scripts.Net.API; +using Assets.MyGame.Scripts.Net.API.UserData_SubClass; using Assets.MyGame.Scripts.Net.APIResponses.Enum; using Assets.MyGame.Scripts.Net.WebResponses; using DG.Tweening; @@ -151,6 +152,10 @@ public class GameMainPanel_FishBase : GameMainPanel_Base public float currBingFengTime = 0f; private Dictionary _frozenAnimSpeeds = new Dictionary(); + // ⭐ 暴走/冰封本地数量:因为暂无扣减 API,激活时本地 -1,避免被 OnUserDataChanged 覆盖回服务端旧值 + private int _localBaoZouCount = -1; // -1 表示尚未初始化 + private int _localBingFengCount = -1; + [Header("Skillleft")] public Button btn_GuaGuaKa; public TextMeshProUGUI tmp_GGKCount; @@ -295,8 +300,6 @@ public class GameMainPanel_FishBase : GameMainPanel_Base var user = GameManager.Instance.user; var props = user?.props; int ggkCount = 0; - int baoZouCount = 0; - int bingFengCount = 0; if (props != null) { @@ -304,19 +307,14 @@ public class GameMainPanel_FishBase : GameMainPanel_Base { if (p.number == "40005" && p.count > 0) ggkCount = p.count; - else if (p.number == "40006" && p.count > 0) - baoZouCount = p.count; - else if (p.number == "40007" && p.count > 0) - bingFengCount = p.count; } } if (tmp_GGKCount != null) tmp_GGKCount.text = ggkCount.ToString(); - if (tmp_BaoZouCount != null) - tmp_BaoZouCount.text = baoZouCount.ToString(); - if (tmp_BingFengCount != null) - tmp_BingFengCount.text = bingFengCount.ToString(); + + // 同步刷新暴走/冰封本地计数(仅首次或服务端数据变化时同步) + RefreshSkillPropsCount(props); // 同步更新游戏内金币显示(刮刮卡领奖、邮件领取等都会触发) if (currSitData != null && user?.assets != null) @@ -326,6 +324,42 @@ public class GameMainPanel_FishBase : GameMainPanel_Base currSitData.tMP_GoldNum.text = user.assets.gold.ToString(); } } + + /// + /// 刷新暴走/冰封道具数量显示 + /// 策略:本地计数未初始化(_localXxxCount == -1)时从服务端 props 读取; + /// 之后由激活扣减本地维护,避免 OnUserDataChanged 把本地扣减值覆盖回服务端旧值 + /// + private void RefreshSkillPropsCount(List props) + { + int serverBaoZou = 0; + int serverBingFeng = 0; + if (props != null) + { + foreach (var p in props) + { + if (p.number == "40006" && p.count > 0) serverBaoZou = p.count; + else if (p.number == "40007" && p.count > 0) serverBingFeng = p.count; + } + } + + // 首次初始化,或服务端数量比本地少(说明服务端已扣减,比如其他端使用)→ 以服务端为准 + if (_localBaoZouCount < 0 || serverBaoZou < _localBaoZouCount) + _localBaoZouCount = serverBaoZou; + if (_localBingFengCount < 0 || serverBingFeng < _localBingFengCount) + _localBingFengCount = serverBingFeng; + + UpdateSkillPropsUI(); + } + + /// 仅更新 UI 文本 + private void UpdateSkillPropsUI() + { + if (tmp_BaoZouCount != null) + tmp_BaoZouCount.text = Mathf.Max(0, _localBaoZouCount).ToString(); + if (tmp_BingFengCount != null) + tmp_BingFengCount.text = Mathf.Max(0, _localBingFengCount).ToString(); + } protected override void OnHide() { base.OnHide(); @@ -339,6 +373,9 @@ public class GameMainPanel_FishBase : GameMainPanel_Base // 清除场景加载标记,下次进入可重新加载 Assets.MyGame.Scripts.Net.WebSocketReponseList.ClearLoadedGameScene(sceneName); WebSocketManager.Instance.Close(SocketType.game); + // ⭐ 重置本地道具计数,下次进入房间重新从服务端读取 + _localBaoZouCount = -1; + _localBingFengCount = -1; } #endregion @@ -504,7 +541,16 @@ public class GameMainPanel_FishBase : GameMainPanel_Base // UI 开关只是触发,但最终状态以 currGameType 为准 CreateFishManager.Instance.currGameType.isFrenzy = on; SetFrenzy(on); - if (on) currFrenzyTime = frenzyDuration; + if (on) + { + currFrenzyTime = frenzyDuration; + // ⭐ 激活时本地扣减一张(暂无扣减 API,仅 UI 显示) + if (_localBaoZouCount > 0) + { + _localBaoZouCount--; + UpdateSkillPropsUI(); + } + } }); toggle_SkillAuto.onValueChanged.AddListener(on => { @@ -520,6 +566,12 @@ public class GameMainPanel_FishBase : GameMainPanel_Base { // 开始冰冻 currBingFengTime = bingFengDuration; + // ⭐ 激活时本地扣减一张(暂无扣减 API,仅 UI 显示) + if (_localBingFengCount > 0) + { + _localBingFengCount--; + UpdateSkillPropsUI(); + } if (bingFengEffect != null) { if (_bingFengInstance == null)