1 using Microsoft.Xna.Framework;
2 using Microsoft.Xna.Framework.Graphics;
4 using System.Collections.Generic;
16 private const int MaxOutOfViewDist = 500;
18 private int particleCount;
21 get {
return particleCount; }
24 private int maxParticles;
27 get {
return maxParticles; }
30 if (maxParticles == value || value < 4) {
return; }
33 for (
int i = 0; i < Math.Min(maxParticles, value); i++)
35 newParticles[i] = particles[i];
38 particleCount = Math.Min(particleCount, value);
39 particles = newParticles;
42 var oldParticlesInCreationOrder = particlesInCreationOrder.ToList();
43 particlesInCreationOrder.Clear();
44 foreach (var particle
in oldParticlesInCreationOrder)
46 if (particles.Contains(particle))
48 particlesInCreationOrder.AddLast(particle);
60 private readonly LinkedList<Particle> particlesInCreationOrder =
new LinkedList<Particle>();
74 MaxParticles = GameSettings.CurrentConfig.Graphics.ParticleLimit;
77 public Particle CreateParticle(
string prefabName, Vector2 position,
float angle,
float speed,
Hull hullGuess =
null,
float collisionIgnoreTimer = 0f, Tuple<Vector2, Vector2> tracerPoints =
null)
79 return CreateParticle(prefabName, position,
new Vector2((
float)Math.Cos(angle), (
float)-Math.Sin(angle)) * speed, angle, hullGuess, collisionIgnoreTimer, tracerPoints: tracerPoints);
82 public Particle CreateParticle(
string prefabName, Vector2 position, Vector2 velocity,
float rotation = 0.0f,
Hull hullGuess =
null,
float collisionIgnoreTimer = 0f, Tuple<Vector2, Vector2> tracerPoints =
null)
88 DebugConsole.ThrowError(
"Particle prefab \"" + prefabName +
"\" not found!");
91 return CreateParticle(prefab, position, velocity, rotation, hullGuess, collisionIgnoreTimer: collisionIgnoreTimer, tracerPoints:tracerPoints);
94 public Particle CreateParticle(
ParticlePrefab prefab, Vector2 position, Vector2 velocity,
float rotation = 0.0f,
Hull hullGuess =
null,
bool drawOnTop =
false,
float collisionIgnoreTimer = 0f,
float lifeTimeMultiplier = 1f, Tuple<Vector2, Vector2> tracerPoints =
null)
96 if (prefab ==
null || prefab.
Sprites.Count == 0) {
return null; }
99 for (
int i = 0; i < particleCount; i++)
113 Vector2 minPos =
new Vector2(Math.Min(position.X, particleEndPos.X), Math.Min(position.Y, particleEndPos.Y));
114 Vector2 maxPos =
new Vector2(Math.Max(position.X, particleEndPos.X), Math.Max(position.Y, particleEndPos.Y));
116 if (tracerPoints !=
null)
118 minPos =
new Vector2(
119 Math.Min(Math.Min(minPos.X, tracerPoints.Item1.X), tracerPoints.Item2.X),
120 Math.Min(Math.Min(minPos.Y, tracerPoints.Item1.Y), tracerPoints.Item2.Y));
121 maxPos =
new Vector2(
122 Math.Max(Math.Max(maxPos.X, tracerPoints.Item1.X), tracerPoints.Item2.X),
123 Math.Max(Math.Max(maxPos.Y, tracerPoints.Item1.Y), tracerPoints.Item2.Y));
130 if (minPos.X > expandedViewRect.Right || maxPos.X < expandedViewRect.X) {
return null; }
131 if (minPos.Y > expandedViewRect.Y || maxPos.Y < expandedViewRect.Y - expandedViewRect.Height) {
return null; }
134 if (particles[particleCount] ==
null) { particles[particleCount] =
new Particle(); }
135 Particle particle = particles[particleCount];
137 particle.
Init(prefab, position, velocity, rotation, hullGuess, drawOnTop, collisionIgnoreTimer, lifeTimeMultiplier, tracerPoints: tracerPoints);
139 particlesInCreationOrder.AddFirst(particle);
155 private void RemoveParticle(
int index)
157 particlesInCreationOrder.Remove(particles[index]);
160 (particles[particleCount], particles[index]) = (particles[index], particles[particleCount]);
166 for (
int i = 0; i < particleCount; i++)
168 if (particles[i] == particle)
178 MaxParticles = GameSettings.CurrentConfig.Graphics.ParticleLimit;
180 for (
int i = 0; i < particleCount; i++)
189 DebugConsole.ThrowError(
"Particle update failed", e);
193 if (
remove) { RemoveParticle(i); }
199 for (
int i = 0; i < particleCount; i++)
207 Dictionary<ParticlePrefab, int> activeParticles =
new Dictionary<ParticlePrefab, int>();
208 for (
int i = 0; i < particleCount; i++)
210 if (!activeParticles.ContainsKey(particles[i].
Prefab)) activeParticles[particles[i].
Prefab] = 0;
211 activeParticles[particles[i].Prefab]++;
213 return activeParticles;
220 foreach (var particle
in particlesInCreationOrder)
222 if (particle.BlendState != blendState) {
continue; }
224 if ((particle.DrawTarget & drawTarget) == 0) {
continue; }
227 bool isOutside = particle.CurrentHull ==
null;
228 if (!particle.DrawOnTop && isOutside == inSub.Value)
234 particle.Draw(spriteBatch);
241 particlesInCreationOrder.Clear();
246 if (particles ==
null) {
return; }
247 for (
int i = particles.Length - 1; i >= 0; i--)
249 if (particles[i]?.
Prefab == prefab)
251 if (i < particleCount) { particleCount--; }
253 particlesInCreationOrder.Remove(particles[particleCount]);
254 Particle swap = particles[particleCount];
255 particles[particleCount] =
null;
UpdateResult Update(float deltaTime)
void Init(ParticlePrefab prefab, Vector2 position, Vector2 speed, float rotation, Hull hullGuess=null, bool drawOnTop=false, float collisionIgnoreTimer=0f, float lifeTimeMultiplier=1f, Tuple< Vector2, Vector2 > tracerPoints=null)
Particle CreateParticle(string prefabName, Vector2 position, float angle, float speed, Hull hullGuess=null, float collisionIgnoreTimer=0f, Tuple< Vector2, Vector2 > tracerPoints=null)
void RemoveByPrefab(ParticlePrefab prefab)
Dictionary< ParticlePrefab, int > CountActiveParticles()
void RemoveParticle(Particle particle)
static List< ParticlePrefab > GetPrefabList()
Particle CreateParticle(ParticlePrefab prefab, Vector2 position, Vector2 velocity, float rotation=0.0f, Hull hullGuess=null, bool drawOnTop=false, float collisionIgnoreTimer=0f, float lifeTimeMultiplier=1f, Tuple< Vector2, Vector2 > tracerPoints=null)
Particle CreateParticle(string prefabName, Vector2 position, Vector2 velocity, float rotation=0.0f, Hull hullGuess=null, float collisionIgnoreTimer=0f, Tuple< Vector2, Vector2 > tracerPoints=null)
ParticleManager(Camera cam)
void Draw(SpriteBatch spriteBatch, bool inWater, bool? inSub, ParticleBlendState blendState)
static ParticlePrefab FindPrefab(string prefabName)
void Update(float deltaTime)
static readonly PrefabCollection< ParticlePrefab > Prefabs
readonly List< Sprite > Sprites
Vector2 CalculateEndPosition(Vector2 startPosition, Vector2 velocity)