Created
July 31, 2020 14:32
-
-
Save profexorgeek/01c4fe51998b06c6a9645864e723eccc to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
namespace Narfox.Utilities | |
{ | |
public enum EmitterScale | |
{ | |
Small = 16, | |
Medium = 64, | |
Large = 256 | |
} | |
public class EasyEmitter : Emitter | |
{ | |
const float DefaultDrag = 3.5f; | |
const float VelocityRangePercent = 0.5f; | |
const float VelocitySizeCoefficient = 6f; | |
const float StartingScaleCoefficient = 0.75f; | |
const float ScaleRangePercent = 0.65f; | |
const float RotationVelocity = 0.25f; | |
const float PiFloat = (float)Math.PI; | |
private static readonly Dictionary<EmitterScale, int> ExplosionParticlesPerScale = new Dictionary<EmitterScale, int> | |
{ | |
{EmitterScale.Small, 8}, | |
{EmitterScale.Medium, 20}, | |
{EmitterScale.Large, 35} | |
}; | |
private static readonly Dictionary<EmitterScale, int> ContrailParticlesPerScale = new Dictionary<EmitterScale, int> | |
{ | |
{EmitterScale.Small, 2}, | |
{EmitterScale.Medium, 8}, | |
{EmitterScale.Large, 12} | |
}; | |
public Color Color | |
{ | |
get | |
{ | |
return color; | |
} | |
set | |
{ | |
color = value; | |
EmissionSettings.Red = color.R / 255f; | |
EmissionSettings.Green = color.G / 255f; | |
EmissionSettings.Blue = color.B / 255f; | |
EmissionSettings.ColorOperation = FlatRedBall.Graphics.ColorOperation.Modulate; | |
} | |
} | |
SpriteList particles { get; set; } = new SpriteList(); | |
Vector3 lastEmissionPosition; | |
EmitterScale emitterScale = EmitterScale.Medium; | |
float emissionDistance = 0; | |
Color color; | |
private EasyEmitter() { } | |
private static Vector2 GetTextureScale(AnimationChain particleChain) | |
{ | |
var frame1 = particleChain[0]; | |
return new Vector2 | |
{ | |
X = frame1.Texture.Width * (frame1.RightCoordinate - frame1.LeftCoordinate) / 2f, | |
Y = frame1.Texture.Height * (frame1.BottomCoordinate - frame1.TopCoordinate) / 2f | |
}; | |
} | |
public static EasyEmitter BuildExplosion( | |
AnimationChain particleChain, | |
EmitterScale scale = EmitterScale.Medium, | |
float lifeSeconds = 1f, | |
float wedgeDegrees = 360f, | |
float scalePerSecond = 0f, | |
float area = 1f) | |
{ | |
var emitter = new EasyEmitter(); | |
emitter.emitterScale = scale; | |
var textureScale = GetTextureScale(particleChain); | |
var radialVelocity = (float)scale * VelocitySizeCoefficient * (1 - VelocityRangePercent); | |
var radialRange = (float)scale * VelocitySizeCoefficient * VelocityRangePercent; | |
emitter.EmissionSettings = new EmissionSettings | |
{ | |
Alpha = 1f, | |
AlphaRate = -1f / lifeSeconds, | |
AnimationChain = particleChain, | |
Animate = true, | |
Drag = DefaultDrag, | |
ScaleX = textureScale.X * StartingScaleCoefficient, | |
ScaleY = textureScale.Y * StartingScaleCoefficient, | |
ScaleXRange = textureScale.X * ScaleRangePercent, | |
ScaleYRange = textureScale.Y * ScaleRangePercent, | |
ScaleXVelocity = scalePerSecond, | |
ScaleYVelocity = scalePerSecond, | |
RotationZ = -PiFloat, | |
RotationZRange = PiFloat * 2f, | |
RotationZVelocity = -RotationVelocity, | |
RotationZVelocityRange = RotationVelocity * 2f, | |
RadialVelocity = radialVelocity, | |
RadialVelocityRange = radialRange, | |
VelocityRangeType = RangeType.Wedge, | |
WedgeAngle = 0, | |
WedgeSpread = wedgeDegrees * (PiFloat / 180f) | |
}; | |
emitter.TimedEmission = false; | |
emitter.SecondFrequency = 0.1f; | |
emitter.RemovalEvent = Emitter.RemovalEventType.Alpha0; | |
emitter.AreaEmission = AreaEmissionType.Rectangle; | |
emitter.ScaleX = area / 2f; | |
emitter.ScaleY = area / 2f; | |
emitter.NumberPerEmission = ExplosionParticlesPerScale[scale]; | |
return emitter; | |
} | |
public static EasyEmitter BuildContrail( | |
AnimationChain particleChain, | |
EmitterScale scale = EmitterScale.Medium, | |
float distance = 8f, | |
float lifeSeconds = 3f, | |
float scalePerSecond = 2f, | |
float area = 1f) | |
{ | |
var emitter = new EasyEmitter(); | |
emitter.emitterScale = scale; | |
emitter.emissionDistance = distance; | |
var textureScale = GetTextureScale(particleChain); | |
emitter.EmissionSettings = new EmissionSettings | |
{ | |
Alpha = 1f, | |
AlphaRate = -1f / lifeSeconds, | |
AnimationChain = particleChain, | |
Animate = true, | |
Drag = DefaultDrag, | |
ScaleY = textureScale.Y * StartingScaleCoefficient, | |
ScaleX = textureScale.X * StartingScaleCoefficient, | |
ScaleYRange = textureScale.Y * StartingScaleCoefficient * ScaleRangePercent, | |
ScaleXRange = textureScale.X * StartingScaleCoefficient * ScaleRangePercent, | |
ScaleYVelocity = scalePerSecond, | |
ScaleXVelocity = scalePerSecond, | |
RotationZ = -PiFloat, | |
RotationZRange = PiFloat * 2f, | |
RotationZVelocity = -0.5f, | |
RotationZVelocityRange = 1f, | |
VelocityRangeType = RangeType.Radial | |
}; | |
emitter.TimedEmission = false; | |
emitter.RemovalEvent = Emitter.RemovalEventType.Alpha0; | |
emitter.AreaEmission = AreaEmissionType.Rectangle; | |
emitter.ScaleX = area / 2f; | |
emitter.ScaleY = area / 2f; | |
emitter.NumberPerEmission = ContrailParticlesPerScale[scale]; | |
return emitter; | |
} | |
public new SpriteList Emit() | |
{ | |
particles.Clear(); | |
Emit(particles); | |
return particles; | |
} | |
public void DistanceEmit() | |
{ | |
var currentPos = Parent?.Position ?? Vector3.Zero; | |
var vectorDelta = (currentPos - lastEmissionPosition).Length(); | |
var elapsedDistance = Math.Abs(vectorDelta); | |
if (elapsedDistance >= emissionDistance) | |
{ | |
this.Emit(); | |
lastEmissionPosition = currentPos; | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment