155 lines
5.2 KiB
C#
155 lines
5.2 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>
|
|
/// 效果传播系统:管理从红色粒子到蓝色粒子的效果传递
|
|
/// </summary>
|
|
public class EffectPropagation
|
|
{
|
|
private CandidateParticle redParticle;
|
|
private List<PropagationInfo> propagatedParticles = new List<PropagationInfo>();
|
|
private List<CandidateParticle> propagationQueue = new List<CandidateParticle>();
|
|
|
|
private float lifeTimer;
|
|
private float propagationDelay = 0.05f;
|
|
private float propagationCounter = 0f;
|
|
private int maxPropagationSteps = 8;
|
|
private int currentPropagationStep = 0;
|
|
|
|
public bool IsActive => lifeTimer > 0;
|
|
public List<PropagationInfo> PropagatedParticles => propagatedParticles;
|
|
|
|
public EffectPropagation(CandidateParticle redParticle, float duration = 1f)
|
|
{
|
|
this.redParticle = redParticle;
|
|
this.lifeTimer = duration;
|
|
|
|
// 从红色粒子开始传播
|
|
var connectedBlues = FindConnectedBlues(redParticle);
|
|
if (connectedBlues.Count > 0 && currentPropagationStep < maxPropagationSteps)
|
|
{
|
|
// 随机选择一个连接的蓝色粒子
|
|
var targetParticle = connectedBlues[Random.Range(0, connectedBlues.Count)];
|
|
ApplyEffectToParticle(targetParticle);
|
|
|
|
// 记录传播信息
|
|
propagatedParticles.Add(new PropagationInfo(targetParticle, redParticle, 1));
|
|
|
|
// 加入传播队列
|
|
propagationQueue.Add(targetParticle);
|
|
currentPropagationStep = 1;
|
|
}
|
|
}
|
|
|
|
public void Update(float deltaTime)
|
|
{
|
|
lifeTimer -= deltaTime;
|
|
propagationCounter += deltaTime;
|
|
|
|
// 定期传播
|
|
if (propagationCounter >= propagationDelay && currentPropagationStep < maxPropagationSteps)
|
|
{
|
|
propagationCounter = 0f;
|
|
|
|
List<CandidateParticle> nextQueue = new List<CandidateParticle>();
|
|
|
|
foreach (var sourceParticle in propagationQueue)
|
|
{
|
|
if (currentPropagationStep >= maxPropagationSteps) break;
|
|
|
|
var connectedBlues = FindConnectedBlues(sourceParticle);
|
|
if (connectedBlues.Count > 0)
|
|
{
|
|
var targetParticle = connectedBlues[Random.Range(0, connectedBlues.Count)];
|
|
ApplyEffectToParticle(targetParticle);
|
|
|
|
currentPropagationStep++;
|
|
|
|
propagatedParticles.Add(new PropagationInfo(targetParticle, sourceParticle, currentPropagationStep));
|
|
|
|
if (currentPropagationStep < maxPropagationSteps)
|
|
{
|
|
nextQueue.Add(targetParticle);
|
|
}
|
|
}
|
|
}
|
|
|
|
propagationQueue = nextQueue;
|
|
}
|
|
|
|
// 更新所有传播粒子的脉冲动画
|
|
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();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|