05281816
This commit is contained in:
Binary file not shown.
@@ -8,5 +8,6 @@ public class ConstEventString
|
||||
public const string SyncGameData_RendromDieFish = "SyncGameData_RenderDieFish";
|
||||
public const string SyncGameData_TurretState = "SyncGameData_TurretState";
|
||||
public const string SyncGameData_ChangeTurret = "SyncGameData_ChangeTurret";
|
||||
public const string SyncGameData_FreezeFish = "SyncGameData_FreezeFish";
|
||||
}
|
||||
|
||||
|
||||
@@ -96,6 +96,8 @@ public class CreateFishManager : MonoSingleton<CreateFishManager>
|
||||
public Dictionary<string, RoomFishDetailConfig> spawnDic;
|
||||
|
||||
public bool isCreateFish; //是否可以创建鱼
|
||||
public bool isFrozen = false; //是否冰冻中(冻结出鱼+所有鱼定格)
|
||||
private Dictionary<string, CharacterStateType> frozenFishStates = new Dictionary<string, CharacterStateType>();
|
||||
|
||||
/// <summary>按鱼类型分类的生成配置(Boss / 普通 / 黄金…)</summary>
|
||||
private Dictionary<FishTypeEnum, List<RoomFishDetailConfig>> fishTypeConfig;
|
||||
@@ -240,7 +242,8 @@ public class CreateFishManager : MonoSingleton<CreateFishManager>
|
||||
|
||||
private void Update()
|
||||
{
|
||||
isCreateFish = BroadCastCreateFish();
|
||||
if (!isFrozen)
|
||||
isCreateFish = BroadCastCreateFish();
|
||||
}
|
||||
|
||||
|
||||
@@ -902,6 +905,7 @@ public class CreateFishManager : MonoSingleton<CreateFishManager>
|
||||
/// <param name="syncGameData"></param>
|
||||
public void CreateFish(SyncGameData syncGameData)
|
||||
{
|
||||
if (isFrozen) return; // 冰冻中不创建鱼
|
||||
var rotateData = FrameDataParser.Parse<FrameData_CreateFish>(syncGameData.frameData);
|
||||
if (rotateData != null)
|
||||
SpawnFishMainThread(rotateData, syncGameData.time);
|
||||
@@ -1487,7 +1491,9 @@ public class CreateFishManager : MonoSingleton<CreateFishManager>
|
||||
{
|
||||
if (item.user == killFish.userId)
|
||||
{
|
||||
item.monCotl_Lock = null;
|
||||
// 只有死的鱼正好是当前锁定目标时才清除
|
||||
if (item.monCotl_Lock != null && item.monCotl_Lock.guid == killFish.fishId)
|
||||
item.monCotl_Lock = null;
|
||||
//item.lockFX.gameObject.SetActive(false);
|
||||
sitData = item;
|
||||
}
|
||||
@@ -1681,4 +1687,54 @@ public class CreateFishManager : MonoSingleton<CreateFishManager>
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
#region 冰冻技能
|
||||
/// <summary>
|
||||
/// 冰冻:记录所有鱼当前状态并强制切到 Idle(暂停移动+动画)
|
||||
/// </summary>
|
||||
public void FreezeAllFish()
|
||||
{
|
||||
isFrozen = true;
|
||||
frozenFishStates.Clear();
|
||||
|
||||
// 只遍历全量字典 fishDatas_hashCodekey(已包含所有鱼),不重复遍历子字典
|
||||
if (fishDatas_hashCodekey != null)
|
||||
{
|
||||
foreach (var kv in fishDatas_hashCodekey)
|
||||
{
|
||||
MonsterContral m = kv.Value;
|
||||
if (m == null || !m.gameObject.activeInHierarchy) continue;
|
||||
|
||||
// 记录原状态
|
||||
frozenFishStates[m.guid] = m.currState;
|
||||
// 定格
|
||||
m.isMove = false;
|
||||
m.ChangeState(CharacterStateType.idle);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 解冻:恢复鱼到冰冻前状态
|
||||
/// </summary>
|
||||
public void UnfreezeAllFish()
|
||||
{
|
||||
isFrozen = false;
|
||||
|
||||
if (fishDatas_hashCodekey != null)
|
||||
{
|
||||
foreach (var kv in fishDatas_hashCodekey)
|
||||
{
|
||||
MonsterContral m = kv.Value;
|
||||
if (m == null || !m.gameObject.activeInHierarchy) continue;
|
||||
|
||||
m.isMove = true;
|
||||
if (frozenFishStates.TryGetValue(m.guid, out var prevState))
|
||||
m.ChangeState(prevState);
|
||||
}
|
||||
}
|
||||
|
||||
frozenFishStates.Clear();
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
|
||||
@@ -48,7 +48,8 @@ namespace Assets.MyGame.Scripts.Net.WebResponses
|
||||
changeAutoTarget=4,
|
||||
randomDieFish=5,
|
||||
changeTurretState=6,
|
||||
changeTurret=7
|
||||
changeTurret=7,
|
||||
freezeFish=8
|
||||
|
||||
}
|
||||
[Serializable]
|
||||
@@ -93,6 +94,8 @@ namespace Assets.MyGame.Scripts.Net.WebResponses
|
||||
public bool twoRTruuect;
|
||||
public string monsterID;
|
||||
public bool isZuanTou;
|
||||
/// <summary>三发锁定时每个子弹对应的鱼 GUID(3个),按优先级排序</summary>
|
||||
public List<string> monsterIDs;
|
||||
}
|
||||
[Serializable]
|
||||
public class FrameData_CreateFish : FrameData
|
||||
@@ -127,4 +130,9 @@ namespace Assets.MyGame.Scripts.Net.WebResponses
|
||||
{
|
||||
public int turretIndex;
|
||||
}
|
||||
[Serializable]
|
||||
public class FrameData_FreezeFish : FrameData
|
||||
{
|
||||
public bool isFreeze; // true=冰冻开始, false=解冻结束
|
||||
}
|
||||
}
|
||||
|
||||
@@ -202,6 +202,9 @@ namespace Assets.MyGame.Scripts.Net
|
||||
case FrameDataType.randomDieFish:
|
||||
EventCenter.Instance.EventTrigger<SyncGameData>(ConstEventString.SyncGameData_RendromDieFish, syncGameData);
|
||||
break;
|
||||
case FrameDataType.freezeFish:
|
||||
EventCenter.Instance.EventTrigger<SyncGameData>(ConstEventString.SyncGameData_FreezeFish, syncGameData);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -91,6 +91,7 @@ using Spine.Unity;
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
@@ -240,6 +241,7 @@ public class GameMainPanel_FishBase : GameMainPanel_Base
|
||||
EventCenter.Instance.AddEventListener<SyncGameData>(ConstEventString.SyncGameData_RendromDieFish, SyncGameData_RendromDieFish);
|
||||
EventCenter.Instance.AddEventListener<SyncGameData>(ConstEventString.SyncGameData_TurretState, SyncGameData_TurretState);
|
||||
EventCenter.Instance.AddEventListener<SyncGameData>(ConstEventString.SyncGameData_ChangeTurret, SyncGameData_ChangeTurret);
|
||||
EventCenter.Instance.AddEventListener<SyncGameData>(ConstEventString.SyncGameData_FreezeFish, SyncGameData_FreezeFish);
|
||||
|
||||
|
||||
}
|
||||
@@ -251,6 +253,7 @@ public class GameMainPanel_FishBase : GameMainPanel_Base
|
||||
EventCenter.Instance.RemoveEventListener<SyncGameData>(ConstEventString.SyncGameData_RendromDieFish, SyncGameData_RendromDieFish);
|
||||
EventCenter.Instance.RemoveEventListener<SyncGameData>(ConstEventString.SyncGameData_TurretState, SyncGameData_TurretState);
|
||||
EventCenter.Instance.RemoveEventListener<SyncGameData>(ConstEventString.SyncGameData_ChangeTurret, SyncGameData_ChangeTurret);
|
||||
EventCenter.Instance.RemoveEventListener<SyncGameData>(ConstEventString.SyncGameData_FreezeFish, SyncGameData_FreezeFish);
|
||||
|
||||
|
||||
|
||||
@@ -290,6 +293,7 @@ public class GameMainPanel_FishBase : GameMainPanel_Base
|
||||
// UI 开关只是触发,但最终状态以 currGameType 为准
|
||||
CreateFishManager.Instance.currGameType.isFrenzy = on;
|
||||
SetFrenzy(on);
|
||||
if (on) currFrenzyTime = frenzyDuration;
|
||||
});
|
||||
toggle_SkillAuto.onValueChanged.AddListener(on =>
|
||||
{
|
||||
@@ -299,10 +303,23 @@ public class GameMainPanel_FishBase : GameMainPanel_Base
|
||||
currSitData.ChangeState(TurretState.Idle);
|
||||
}
|
||||
});
|
||||
toggle_BingFeng.onValueChanged.AddListener(on => {
|
||||
|
||||
|
||||
|
||||
toggle_BingFeng.onValueChanged.AddListener(on => {
|
||||
if (on)
|
||||
{
|
||||
// 开始冰冻
|
||||
currBingFengTime = bingFengDuration;
|
||||
CreateFishManager.Instance.FreezeAllFish();
|
||||
SyncFreeze(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
// 手动关闭 → 解冻
|
||||
if (CreateFishManager.Instance.isFrozen)
|
||||
{
|
||||
CreateFishManager.Instance.UnfreezeAllFish();
|
||||
SyncFreeze(false);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -357,6 +374,7 @@ public class GameMainPanel_FishBase : GameMainPanel_Base
|
||||
HandleAutoLock();
|
||||
LoopLaser();
|
||||
SettingClose();
|
||||
DaoJiShi();
|
||||
|
||||
}
|
||||
float sittingTime = 10;
|
||||
@@ -768,6 +786,7 @@ public class GameMainPanel_FishBase : GameMainPanel_Base
|
||||
{
|
||||
toggle_BingFeng.isOn = false;
|
||||
img_BingFeng.fillAmount = 1;
|
||||
// 解冻由 toggle.onValueChanged(false) 触发,不在此重复
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -789,10 +808,47 @@ public class GameMainPanel_FishBase : GameMainPanel_Base
|
||||
//FireBullet(currSitData, angle, isSanShe, isDouble, isLock);
|
||||
SyncFire(angle, isSanShe, isDouble, isLock);
|
||||
}
|
||||
private void FireBullet(SitPosData sit, float angle, bool isSanShe, bool isDouble, bool isLock,List<string> bullitIDs)
|
||||
private void FireBullet(SitPosData sit, float angle, bool isSanShe, bool isDouble, bool isLock, List<string> bullitIDs,
|
||||
List<string> fireTargetMonsterIDs = null)
|
||||
{
|
||||
Vector2 startPos = sit.GetBulletStartPos();
|
||||
if (isSanShe)
|
||||
|
||||
// ⭐ 三发 + 锁定 + 有多目标:每发子弹瞄准不同的目标
|
||||
if (isSanShe && isLock && fireTargetMonsterIDs != null && fireTargetMonsterIDs.Count > 0)
|
||||
{
|
||||
for (int i = 0; i < 3 && i < fireTargetMonsterIDs.Count; i++)
|
||||
{
|
||||
// 按 GUID 查找目标
|
||||
MonsterContral targetMonster = null;
|
||||
Transform targetHitPos = null;
|
||||
if (CreateFishManager.Instance.fishDatas_hashCodekey.TryGetValue(fireTargetMonsterIDs[i], out var m)
|
||||
&& m != null && m.gameObject.activeInHierarchy)
|
||||
{
|
||||
targetMonster = m;
|
||||
targetHitPos = m.transform;
|
||||
// 优先用活跃 collider
|
||||
if (m.colliderList != null)
|
||||
{
|
||||
foreach (var col in m.colliderList)
|
||||
{
|
||||
if (col.gameObject.activeInHierarchy) { targetHitPos = col; break; }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (targetMonster != null)
|
||||
{
|
||||
// 计算朝目标的角度
|
||||
Vector3 targetWorldPos = targetHitPos.position;
|
||||
Vector2 dir = ((Vector2)targetWorldPos - startPos).normalized;
|
||||
float targetAngle = Mathf.Atan2(dir.y, dir.x) * Mathf.Rad2Deg - 90f;
|
||||
|
||||
string bulletId = i < bullitIDs.Count ? bullitIDs[i] : bullitIDs[0];
|
||||
CreateBullet(sit, startPos, targetAngle, isDouble, true, bulletId, targetMonster, targetHitPos);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (isSanShe)
|
||||
{
|
||||
CreateBullet(sit, startPos, angle - 20, isDouble, isLock, bullitIDs[0]);
|
||||
CreateBullet(sit, startPos, angle, isDouble, isLock, bullitIDs[1]);
|
||||
@@ -881,6 +937,83 @@ public class GameMainPanel_FishBase : GameMainPanel_Base
|
||||
|
||||
|
||||
|
||||
#endregion
|
||||
|
||||
#region 多目标查找(TripleLock)
|
||||
/// <summary>鱼锁定优先级:特殊Boss(5) > Boss鱼(4) > 特殊鱼(3) > 黄金鱼(2) > 普通鱼(1)</summary>
|
||||
private int GetFishLockPriority(MonsterContral monster)
|
||||
{
|
||||
switch (monster.fishenum)
|
||||
{
|
||||
case FishTypeEnum.特殊Boss: return 5;
|
||||
case FishTypeEnum.Boss鱼: return 4;
|
||||
case FishTypeEnum.特殊鱼: return 3;
|
||||
case FishTypeEnum.黄金鱼: return 2;
|
||||
case FishTypeEnum.普通鱼: return 1;
|
||||
default: return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找 fire 时的多目标(三发锁定用)。
|
||||
/// 第一个目标 = 主锁 monCotl_Lock(打哪锁哪),剩余从 Boss/特殊Boss/特殊鱼/黄金鱼 按优先级补满
|
||||
/// </summary>
|
||||
private List<(MonsterContral monster, Transform hitPos)> FindFireTargets(int maxCount)
|
||||
{
|
||||
var result = new List<(MonsterContral monster, Transform hitPos)>();
|
||||
var selected = new HashSet<string>();
|
||||
|
||||
if (CreateFishManager.Instance == null) return result;
|
||||
|
||||
// ① 主锁目标排第一(打哪锁哪)
|
||||
if (currSitData.isLock && currSitData.monCotl_Lock != null &&
|
||||
currSitData.monCotl_Lock.gameObject.activeInHierarchy)
|
||||
{
|
||||
Transform pos = currSitData.monCotl_Lock_Position != null && currSitData.monCotl_Lock_Position.gameObject.activeInHierarchy
|
||||
? currSitData.monCotl_Lock_Position
|
||||
: currSitData.monCotl_Lock.transform;
|
||||
result.Add((currSitData.monCotl_Lock, pos));
|
||||
selected.Add(currSitData.monCotl_Lock.guid);
|
||||
if (result.Count >= maxCount) return result;
|
||||
}
|
||||
|
||||
// ② 按优先级从分类字典补满剩余位置
|
||||
var dicts = new Dictionary<string, MonsterContral>[]
|
||||
{
|
||||
CreateFishManager.Instance.fishDatas_hashCodekey_TS_Boss,
|
||||
CreateFishManager.Instance.fishDatas_hashCodekey_Boss,
|
||||
CreateFishManager.Instance.fishDatas_hashCodekey_TS,
|
||||
CreateFishManager.Instance.fishDatas_hashCodekey_HJ,
|
||||
};
|
||||
|
||||
foreach (var dict in dicts)
|
||||
{
|
||||
if (dict == null) continue;
|
||||
|
||||
foreach (var kv in dict)
|
||||
{
|
||||
MonsterContral m = kv.Value;
|
||||
if (m == null || !m.gameObject.activeInHierarchy) continue;
|
||||
if (selected.Contains(m.guid)) continue; // 跳过已选中的
|
||||
|
||||
Transform pos = m.transform;
|
||||
if (m.colliderList != null)
|
||||
{
|
||||
foreach (var col in m.colliderList)
|
||||
{
|
||||
if (col.gameObject.activeInHierarchy) { pos = col; break; }
|
||||
}
|
||||
}
|
||||
|
||||
result.Add((m, pos));
|
||||
selected.Add(m.guid);
|
||||
|
||||
if (result.Count >= maxCount) return result;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region 锁定系统(LockModule)
|
||||
@@ -1056,7 +1189,8 @@ public class GameMainPanel_FishBase : GameMainPanel_Base
|
||||
#endregion
|
||||
|
||||
#region BulletModule(子弹系统)
|
||||
private BullitMove CreateBullet(SitPosData sit, Vector2 pos, float angle, bool isDouble, bool isLock,string id)
|
||||
private BullitMove CreateBullet(SitPosData sit, Vector2 pos, float angle, bool isDouble, bool isLock, string id,
|
||||
MonsterContral lockTarget = null, Transform lockHitPos = null)
|
||||
{
|
||||
GameObject prefab = isDouble ? sit.currentTurret.bulletPrefab_Two : sit.currentTurret.bulletPrefab;
|
||||
|
||||
@@ -1071,7 +1205,12 @@ public class GameMainPanel_FishBase : GameMainPanel_Base
|
||||
bullet.bulletID = id;
|
||||
|
||||
if (isLock)
|
||||
bullet.Lock(sit.monCotl_Lock, currSitData.monCotl_Lock_Position);
|
||||
{
|
||||
if (lockTarget != null)
|
||||
bullet.Lock(lockTarget, lockHitPos);
|
||||
else
|
||||
bullet.Lock(sit.monCotl_Lock, currSitData.monCotl_Lock_Position);
|
||||
}
|
||||
|
||||
return bullet;
|
||||
}
|
||||
@@ -1093,20 +1232,30 @@ public class GameMainPanel_FishBase : GameMainPanel_Base
|
||||
|
||||
private void SyncFire(float angle, bool isSanShe, bool isDouble, bool isLock)
|
||||
{
|
||||
var fireData = new FrameData_FireBullit
|
||||
{
|
||||
angle = angle,
|
||||
gold = currSitData.goldNum,
|
||||
isSanShe = isSanShe,
|
||||
twoRTruuect = isDouble,
|
||||
isSuoDing = isLock,
|
||||
auto = toggle_SkillAuto.isOn
|
||||
};
|
||||
|
||||
// ⭐ 三发 + 锁定:查找 3 个优先级目标,写入 monsterIDs
|
||||
if (isSanShe && isLock)
|
||||
{
|
||||
var targets = FindFireTargets(3);
|
||||
if (targets.Count > 0)
|
||||
fireData.monsterIDs = targets.Select(t => t.monster.guid).ToList();
|
||||
}
|
||||
|
||||
SyncGameData sgd = new SyncGameData
|
||||
{
|
||||
sitPos = currSitData.posID,
|
||||
frameType = FrameDataType.fireBullet,
|
||||
time = BeijingTimeManager.Instance.CurrentTimestampMs,
|
||||
frameData = new FrameData_FireBullit
|
||||
{
|
||||
angle = angle,
|
||||
gold = currSitData.goldNum,
|
||||
isSanShe = isSanShe,
|
||||
twoRTruuect = isDouble,
|
||||
isSuoDing = isLock,
|
||||
auto = toggle_SkillAuto.isOn
|
||||
}
|
||||
frameData = fireData
|
||||
};
|
||||
//WebSocketSendList.SyncGameData(sgd);
|
||||
var roomdata = GameManager.Instance.gameData.currRoomData;
|
||||
@@ -1173,6 +1322,18 @@ public class GameMainPanel_FishBase : GameMainPanel_Base
|
||||
WebSocketSendList.SyncGameData(sgd);
|
||||
}
|
||||
|
||||
private void SyncFreeze(bool isFreeze)
|
||||
{
|
||||
SyncGameData sgd = new SyncGameData
|
||||
{
|
||||
sitPos = currSitData.posID,
|
||||
frameType = FrameDataType.freezeFish,
|
||||
time = BeijingTimeManager.Instance.CurrentTimestampMs,
|
||||
frameData = new FrameData_FreezeFish { isFreeze = isFreeze }
|
||||
};
|
||||
WebSocketSendList.SyncGameData(sgd);
|
||||
}
|
||||
|
||||
|
||||
#endregion
|
||||
|
||||
@@ -1190,7 +1351,7 @@ public class GameMainPanel_FishBase : GameMainPanel_Base
|
||||
//if (sync.sitPos == currSitData.posID) return;
|
||||
|
||||
var data = FrameDataParser.Parse<FrameData_FireBullit>(sync.extra.frameData);
|
||||
FireBullet(list_Sits[sync.extra.sitPos], data.angle, data.isSanShe, data.twoRTruuect, data.isSuoDing,sync.bulletIds);
|
||||
FireBullet(list_Sits[sync.extra.sitPos], data.angle, data.isSanShe, data.twoRTruuect, data.isSuoDing, sync.bulletIds, data.monsterIDs);
|
||||
}
|
||||
|
||||
public void SyncGameData_ChangeTargetMonster(SyncGameData sync)
|
||||
@@ -1242,6 +1403,17 @@ public class GameMainPanel_FishBase : GameMainPanel_Base
|
||||
list_Sits[sync.sitPos].ChangeTurret(data.turretIndex);
|
||||
}
|
||||
|
||||
public void SyncGameData_FreezeFish(SyncGameData sync)
|
||||
{
|
||||
if (sync.sitPos == currSitData.posID) return; // 自己发的不管
|
||||
|
||||
var data = FrameDataParser.Parse<FrameData_FreezeFish>(sync.frameData);
|
||||
if (data.isFreeze)
|
||||
CreateFishManager.Instance.FreezeAllFish();
|
||||
else
|
||||
CreateFishManager.Instance.UnfreezeAllFish();
|
||||
}
|
||||
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
@@ -3521,6 +3521,13 @@ MonoBehaviour:
|
||||
toggle_Three: {fileID: 748668496574007314}
|
||||
toggle_Shuang: {fileID: 870607161084201748}
|
||||
toggle_BaoZou: {fileID: 6820470193323630788}
|
||||
img_BaoZou: {fileID: 4519855428832475769}
|
||||
frenzyDuration: 5
|
||||
currFrenzyTime: 0
|
||||
toggle_BingFeng: {fileID: 7126682788597616111}
|
||||
img_BingFeng: {fileID: 734296607713292731}
|
||||
bingFengDuration: 5
|
||||
currBingFengTime: 0
|
||||
list_Sits:
|
||||
- {fileID: 1736561711096904313}
|
||||
- {fileID: 9022000259197046427}
|
||||
@@ -4483,7 +4490,7 @@ MonoBehaviour:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
m_Sprite: {fileID: 21300000, guid: 698df028996d4c14dace6f08d1aa8452, type: 3}
|
||||
m_Type: 0
|
||||
m_Type: 3
|
||||
m_PreserveAspect: 0
|
||||
m_FillCenter: 1
|
||||
m_FillMethod: 4
|
||||
|
||||
Reference in New Issue
Block a user