Files
aibis-dream/Assets/Scripts/MiniGame/HuoShan/Language/EffectPropagation.cs
T
2025-11-13 20:30:13 +08:00

157 lines
5.5 KiB
C#

using UnityEngine;
using System.Collections.Generic;
namespace AibisDream.MiniGame.Language
{
/// <summary>
/// 效果传播信息
/// </summary>
public class PropagationInfo
{
public CandidateParticle particle;
public CandidateParticle source;
public int step;
public float pulseProgress;
public PropagationInfo(CandidateParticle particle, CandidateParticle source, int step)
{
this.particle = particle;
this.source = source;
this.step = step;
this.pulseProgress = 0f;
}
}
/// <summary>
/// 效果传播系统:管理从红色粒子到蓝色粒子的效果传递(使用BFS算法)
/// </summary>
public class EffectPropagation
{
private CandidateParticle redParticle;
private List<PropagationInfo> propagatedParticles = new List<PropagationInfo>();
private Queue<CandidateParticle> propagationQueue = new Queue<CandidateParticle>();
private float lifeTimer;
private float propagationDelay;
private float propagationCounter = 0f;
private int maxPropagationNodes;
private int currentNodeCount = 0;
private int currentStep = 0;
public bool IsActive => lifeTimer > 0;
public List<PropagationInfo> PropagatedParticles => propagatedParticles;
public EffectPropagation(CandidateParticle redParticle, float duration, float delay, int maxNodes)
{
this.redParticle = redParticle;
this.lifeTimer = duration;
this.propagationDelay = delay;
this.maxPropagationNodes = maxNodes;
// 从红色粒子开始传播(第0步)
var connectedBlues = FindConnectedBlues(redParticle);
if (connectedBlues.Count > 0 && currentNodeCount < maxPropagationNodes)
{
// 第一步:处理所有直接连接的蓝色粒子(BFS第一层)
foreach (var targetParticle in connectedBlues)
{
if (currentNodeCount >= maxPropagationNodes) break;
ApplyEffectToParticle(targetParticle);
propagatedParticles.Add(new PropagationInfo(targetParticle, redParticle, 1));
propagationQueue.Enqueue(targetParticle);
currentNodeCount++;
}
currentStep = 1;
}
}
public void Update(float deltaTime)
{
lifeTimer -= deltaTime;
propagationCounter += deltaTime;
// BFS逐层传播
if (propagationCounter >= propagationDelay && propagationQueue.Count > 0 && currentNodeCount < maxPropagationNodes)
{
propagationCounter = 0f;
currentStep++;
// 处理当前层的所有节点
int currentLevelSize = propagationQueue.Count;
for (int i = 0; i < currentLevelSize; i++)
{
if (currentNodeCount >= maxPropagationNodes) break;
var sourceParticle = propagationQueue.Dequeue();
var connectedBlues = FindConnectedBlues(sourceParticle);
// 将所有连接的蓝色粒子加入下一层
foreach (var targetParticle in connectedBlues)
{
if (currentNodeCount >= maxPropagationNodes) break;
ApplyEffectToParticle(targetParticle);
propagatedParticles.Add(new PropagationInfo(targetParticle, sourceParticle, currentStep + 1));
propagationQueue.Enqueue(targetParticle);
currentNodeCount++;
}
}
}
// 更新所有传播粒子的脉冲动画
foreach (var info in propagatedParticles)
{
info.pulseProgress += deltaTime * 5f;
if (info.pulseProgress > 1f)
info.pulseProgress = 1f;
}
}
private List<CandidateParticle> FindConnectedBlues(CandidateParticle particle)
{
List<CandidateParticle> connected = new List<CandidateParticle>();
HashSet<CandidateParticle> usedParticles = new HashSet<CandidateParticle>();
// 记录已使用的粒子
usedParticles.Add(redParticle);
foreach (var prop in propagatedParticles)
{
usedParticles.Add(prop.particle);
}
// 只检查真正连接的粒子
foreach (var connectedParticle in particle.connections)
{
if (!connectedParticle.hasEffect &&
!usedParticles.Contains(connectedParticle) &&
!connectedParticle.isRed &&
!connectedParticle.isOrange)
{
connected.Add(connectedParticle);
}
}
return connected;
}
private void ApplyEffectToParticle(CandidateParticle particle)
{
if (particle.hasEffect) return;
if (particle.isRed && particle.originalIsRed) return;
particle.ApplyEffect(lifeTimer);
}
public void Cleanup()
{
foreach (var info in propagatedParticles)
{
info.particle.RemoveEffect();
}
}
}
}