Separate ParticleEmitter & ParticleEmitterPrefab classes - the emission timer (and maybe some other values in the future) can't be in the prefab class because multiple objects may use the same prefab.

This commit is contained in:
Joonas Rikkonen
2017-08-20 22:05:30 +03:00
parent 04834f9f7f
commit cc40970b58
4 changed files with 68 additions and 49 deletions
@@ -8,7 +8,7 @@ namespace Barotrauma
{ {
private Sound sound; private Sound sound;
private ParticleEmitter particleEmitterPrefab; private ParticleEmitter particleEmitter;
partial void InitProjSpecific(XElement element) partial void InitProjSpecific(XElement element)
{ {
@@ -23,7 +23,7 @@ namespace Barotrauma
switch (subElement.Name.ToString().ToLowerInvariant()) switch (subElement.Name.ToString().ToLowerInvariant())
{ {
case "particleemitter": case "particleemitter":
particleEmitterPrefab = new ParticleEmitter(subElement); particleEmitter = new ParticleEmitter(subElement);
break; break;
} }
@@ -32,9 +32,9 @@ namespace Barotrauma
partial void DamageParticles(float deltaTime, Vector2 worldPosition) partial void DamageParticles(float deltaTime, Vector2 worldPosition)
{ {
if (particleEmitterPrefab != null) if (particleEmitter != null)
{ {
particleEmitterPrefab.Emit(deltaTime, worldPosition); particleEmitter.Emit(deltaTime, worldPosition);
} }
if (sound != null) if (sound != null)
@@ -1,4 +1,5 @@
using Microsoft.Xna.Framework; using Barotrauma.Particles;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics; using Microsoft.Xna.Framework.Graphics;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
@@ -16,6 +17,8 @@ namespace Barotrauma
public float Scale; public float Scale;
public float Rotation; public float Rotation;
public Particles.ParticleEmitter ParticleEmitter;
//public Vector2[] spriteCorners; //public Vector2[] spriteCorners;
@@ -27,6 +30,8 @@ namespace Barotrauma
this.Scale = scale; this.Scale = scale;
this.Rotation = rotation; this.Rotation = rotation;
this.ParticleEmitter = new ParticleEmitter(prefab.ParticleEmitterPrefab);
} }
} }
@@ -240,7 +245,7 @@ namespace Barotrauma
foreach (BackgroundSprite s in visibleSprites) foreach (BackgroundSprite s in visibleSprites)
{ {
if (s.Prefab.ParticleEmitter != null) if (s.Prefab.ParticleEmitterPrefab != null)
{ {
Vector2 emitterPos = new Vector2(s.Prefab.EmitterPosition.X, s.Prefab.EmitterPosition.Y); Vector2 emitterPos = new Vector2(s.Prefab.EmitterPosition.X, s.Prefab.EmitterPosition.Y);
@@ -254,7 +259,7 @@ namespace Barotrauma
-sa * emitterPos.X + ca * emitterPos.Y); -sa * emitterPos.X + ca * emitterPos.Y);
} }
s.Prefab.ParticleEmitter.Emit(deltaTime, new Vector2(s.Position.X, s.Position.Y) + emitterPos); s.ParticleEmitter.Emit(deltaTime, new Vector2(s.Position.X, s.Position.Y) + emitterPos);
} }
} }
@@ -30,7 +30,7 @@ namespace Barotrauma
public readonly Vector2 DepthRange; public readonly Vector2 DepthRange;
public readonly Particles.ParticleEmitter ParticleEmitter; public readonly Particles.ParticleEmitterPrefab ParticleEmitterPrefab;
public readonly Vector2 EmitterPosition; public readonly Vector2 EmitterPosition;
public readonly float SwingAmount; public readonly float SwingAmount;
@@ -90,7 +90,7 @@ namespace Barotrauma
} }
break; break;
case "particleemitter": case "particleemitter":
ParticleEmitter = new Particles.ParticleEmitter(subElement); ParticleEmitterPrefab = new Particles.ParticleEmitterPrefab(subElement);
EmitterPosition = ToolBox.GetAttributeVector2(subElement, "position", Vector2.Zero); EmitterPosition = ToolBox.GetAttributeVector2(subElement, "position", Vector2.Zero);
break; break;
} }
@@ -5,10 +5,60 @@ using System.Xml.Linq;
namespace Barotrauma.Particles namespace Barotrauma.Particles
{ {
class ParticleEmitter class ParticleEmitter
{
private float emitTimer;
public readonly ParticleEmitterPrefab Prefab;
public ParticleEmitter(XElement element)
{
Prefab = new ParticleEmitterPrefab(element);
}
public ParticleEmitter(ParticleEmitterPrefab prefab)
{
Prefab = prefab;
}
public void Emit(float deltaTime, Vector2 position, Hull hullGuess = null)
{
emitTimer += deltaTime;
if (Prefab.ParticlesPerSecond > 0)
{
float emitInterval = 1.0f / Prefab.ParticlesPerSecond;
while (emitTimer > emitInterval)
{
Emit(position, hullGuess);
emitTimer -= emitInterval;
}
}
for (int i = 0; i < Prefab.ParticleAmount; i++)
{
Emit(position, hullGuess);
}
}
private void Emit(Vector2 position, Hull hullGuess = null)
{
float angle = Rand.Range(Prefab.AngleMin, Prefab.AngleMax);
Vector2 velocity = new Vector2((float)Math.Cos(angle), (float)Math.Sin(angle)) * Rand.Range(Prefab.VelocityMin, Prefab.VelocityMax);
var particle = GameMain.ParticleManager.CreateParticle(Prefab.ParticlePrefab, position, velocity, 0.0f, hullGuess);
if (particle != null)
{
particle.Size *= Rand.Range(Prefab.ScaleMin, Prefab.ScaleMax);
}
}
}
class ParticleEmitterPrefab
{ {
public readonly string Name; public readonly string Name;
public readonly ParticlePrefab particlePrefab; public readonly ParticlePrefab ParticlePrefab;
public readonly float AngleMin, AngleMax; public readonly float AngleMin, AngleMax;
@@ -17,16 +67,13 @@ namespace Barotrauma.Particles
public readonly float ScaleMin, ScaleMax; public readonly float ScaleMin, ScaleMax;
public readonly int ParticleAmount; public readonly int ParticleAmount;
public readonly float ParticlesPerSecond;
public readonly float ParticlesPerSecond; public ParticleEmitterPrefab(XElement element)
private float emitTimer;
public ParticleEmitter(XElement element)
{ {
Name = element.Name.ToString(); Name = element.Name.ToString();
particlePrefab = GameMain.ParticleManager.FindPrefab(ToolBox.GetAttributeString(element, "particle", "")); ParticlePrefab = GameMain.ParticleManager.FindPrefab(ToolBox.GetAttributeString(element, "particle", ""));
if (element.Attribute("startrotation") == null) if (element.Attribute("startrotation") == null)
{ {
@@ -67,38 +114,5 @@ namespace Barotrauma.Particles
ParticlesPerSecond = ToolBox.GetAttributeInt(element, "particlespersecond", 0); ParticlesPerSecond = ToolBox.GetAttributeInt(element, "particlespersecond", 0);
ParticleAmount = ToolBox.GetAttributeInt(element, "particleamount", 0); ParticleAmount = ToolBox.GetAttributeInt(element, "particleamount", 0);
} }
public void Emit(float deltaTime, Vector2 position, Hull hullGuess = null)
{
emitTimer += deltaTime;
if (ParticlesPerSecond > 0)
{
float emitInterval = 1.0f / ParticlesPerSecond;
while (emitTimer > emitInterval)
{
Emit(position, hullGuess);
emitTimer -= emitInterval;
}
}
for (int i = 0; i<ParticleAmount; i++)
{
Emit(position, hullGuess);
}
}
private void Emit(Vector2 position, Hull hullGuess = null)
{
float angle = Rand.Range(AngleMin, AngleMax);
Vector2 velocity = new Vector2((float)Math.Cos(angle), (float)Math.Sin(angle)) * Rand.Range(VelocityMin, VelocityMax);
var particle = GameMain.ParticleManager.CreateParticle(particlePrefab, position, velocity, 0.0f, hullGuess);
if (particle != null)
{
particle.Size *= Rand.Range(ScaleMin, ScaleMax);
}
}
} }
} }