-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
e4e20be
commit cf32626
Showing
3 changed files
with
431 additions
and
0 deletions.
There are no files selected for viewing
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,139 @@ | ||
using Microsoft.Xna.Framework; | ||
using Microsoft.Xna.Framework.Graphics; | ||
using System; | ||
|
||
namespace WeWereBound | ||
{ | ||
public struct Particle | ||
{ | ||
public Entity Track; | ||
public ParticleType Type; | ||
public MTexture Source; | ||
|
||
public bool Active; | ||
public Color Color; | ||
public Color StartColor; | ||
public Vector2 Position; | ||
public Vector2 Speed; | ||
public float Size; | ||
public float StartSize; | ||
public float Life; | ||
public float StartLife; | ||
public float ColorSwitch; | ||
public float Rotation; | ||
public float Spin; | ||
|
||
public bool SimulateFor(float duration) | ||
{ | ||
if (duration > Life) | ||
{ | ||
Life = 0; | ||
Active = false; | ||
return false; | ||
} | ||
else | ||
{ | ||
var dt = GameEngine.TimeRate * (GameEngine.Instance.TargetElapsedTime.Milliseconds / 1000f); | ||
if (dt > 0) | ||
for (var t = 0f; t < duration; t += dt) | ||
Update(dt); | ||
|
||
return true; | ||
} | ||
} | ||
|
||
public void Update(float? delta = null) | ||
{ | ||
var dt = 0f; | ||
if (delta.HasValue) | ||
dt = delta.Value; | ||
else | ||
dt = (Type.UseActualDeltaTime ? GameEngine.RawDeltaTime : GameEngine.DeltaTime); | ||
|
||
var ease = Life / StartLife; | ||
|
||
//Life | ||
Life -= dt; | ||
if (Life <= 0) | ||
{ | ||
Active = false; | ||
return; | ||
} | ||
|
||
//Spin | ||
if (Type.RotationMode == ParticleType.RotationModes.SameAsDirection) | ||
{ | ||
if (Speed != Vector2.Zero) | ||
Rotation = Speed.Angle(); | ||
} | ||
else | ||
Rotation += Spin * dt; | ||
|
||
//Fade | ||
float alpha; | ||
if (Type.FadeMode == ParticleType.FadeModes.Linear) | ||
alpha = ease; | ||
else if (Type.FadeMode == ParticleType.FadeModes.Late) | ||
alpha = Math.Min(1f, ease / .25f); | ||
else if (Type.FadeMode == ParticleType.FadeModes.InAndOut) | ||
{ | ||
if (ease > .75f) | ||
alpha = 1 - ((ease - .75f) / .25f); | ||
else if (ease < .25f) | ||
alpha = ease / .25f; | ||
else | ||
alpha = 1f; | ||
} | ||
else | ||
alpha = 1f; | ||
|
||
|
||
//Color switch with alpha | ||
if (alpha == 0) | ||
Color = Color.Transparent; | ||
else | ||
{ | ||
if (Type.ColorMode == ParticleType.ColorModes.Static) | ||
Color = StartColor; | ||
else if (Type.ColorMode == ParticleType.ColorModes.Fade) | ||
Color = Color.Lerp(Type.Color2, StartColor, ease); | ||
else if (Type.ColorMode == ParticleType.ColorModes.Blink) | ||
Color = (Calc.BetweenInterval(Life, .1f) ? StartColor : Type.Color2); | ||
else if (Type.ColorMode == ParticleType.ColorModes.Choose) | ||
Color = StartColor; | ||
|
||
if (alpha < 1f) | ||
Color *= alpha; | ||
} | ||
|
||
//Speed | ||
Position += Speed * dt; | ||
Speed += Type.Acceleration * dt; | ||
Speed = Calc.Approach(Speed, Vector2.Zero, Type.Friction * dt); | ||
if (Type.SpeedMultiplier != 1) | ||
Speed *= (float)Math.Pow(Type.SpeedMultiplier, dt); | ||
|
||
//Scale Out | ||
if (Type.ScaleOut) | ||
Size = StartSize * Ease.CubeOut(ease); | ||
} | ||
|
||
public void Render() | ||
{ | ||
var renderAt = new Vector2((int)Position.X, (int)Position.Y); | ||
if (Track != null) | ||
renderAt += Track.Position; | ||
|
||
Draw.SpriteBatch.Draw(Source.Texture, renderAt, Source.ClipRect, Color, Rotation, Source.Center, Size, SpriteEffects.None, 0); | ||
} | ||
|
||
public void Render(float alpha) | ||
{ | ||
var renderAt = new Vector2((int)Position.X, (int)Position.Y); | ||
if (Track != null) | ||
renderAt += Track.Position; | ||
|
||
Draw.SpriteBatch.Draw(Source.Texture, renderAt, Source.ClipRect, Color * alpha, Rotation, Source.Center, Size, SpriteEffects.None, 0); | ||
} | ||
} | ||
} |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,134 @@ | ||
using Microsoft.Xna.Framework; | ||
using System; | ||
|
||
namespace WeWereBound | ||
{ | ||
public class ParticleSystem : Entity | ||
{ | ||
private Particle[] particles; | ||
private int nextSlot; | ||
|
||
public ParticleSystem(int depth, int maxParticles) | ||
: base() | ||
{ | ||
particles = new Particle[maxParticles]; | ||
Depth = depth; | ||
} | ||
|
||
public void Clear() | ||
{ | ||
for (int i = 0; i < particles.Length; i++) | ||
particles[i].Active = false; | ||
} | ||
|
||
public void ClearRect(Rectangle rect, bool inside) | ||
{ | ||
for (int i = 0; i < particles.Length; i++) | ||
{ | ||
var pos = particles[i].Position; | ||
var isInside = (pos.X > rect.Left && pos.Y > rect.Top && pos.X < rect.Right && pos.Y < rect.Bottom); | ||
|
||
if (isInside == inside) | ||
particles[i].Active = false; | ||
} | ||
} | ||
|
||
public override void Update() | ||
{ | ||
for (int i = 0; i < particles.Length; i++) | ||
if (particles[i].Active) | ||
particles[i].Update(); | ||
} | ||
|
||
public override void Render() | ||
{ | ||
foreach (var p in particles) | ||
if (p.Active) | ||
p.Render(); | ||
} | ||
|
||
public void Render(float alpha) | ||
{ | ||
foreach (var p in particles) | ||
if (p.Active) | ||
p.Render(alpha); | ||
} | ||
|
||
public void Simulate(float duration, float interval, Action<ParticleSystem> emitter) | ||
{ | ||
var delta = 0.016f; | ||
for (float time = 0f; time < duration; time += delta) | ||
{ | ||
if ((int)((time - delta) / interval) < (int)(time / interval)) | ||
emitter(this); | ||
|
||
for (int i = 0; i < particles.Length; i++) | ||
if (particles[i].Active) | ||
particles[i].Update(delta); | ||
} | ||
} | ||
|
||
public void Add(Particle particle) | ||
{ | ||
particles[nextSlot] = particle; | ||
nextSlot = (nextSlot + 1) % particles.Length; | ||
} | ||
|
||
public void Emit(ParticleType type, Vector2 position) | ||
{ | ||
type.Create(ref particles[nextSlot], position); | ||
nextSlot = (nextSlot + 1) % particles.Length; | ||
} | ||
|
||
public void Emit(ParticleType type, Vector2 position, float direction) | ||
{ | ||
type.Create(ref particles[nextSlot], position, direction); | ||
nextSlot = (nextSlot + 1) % particles.Length; | ||
} | ||
|
||
public void Emit(ParticleType type, Vector2 position, Color color) | ||
{ | ||
type.Create(ref particles[nextSlot], position, color); | ||
nextSlot = (nextSlot + 1) % particles.Length; | ||
} | ||
|
||
public void Emit(ParticleType type, Vector2 position, Color color, float direction) | ||
{ | ||
type.Create(ref particles[nextSlot], position, color, direction); | ||
nextSlot = (nextSlot + 1) % particles.Length; | ||
} | ||
|
||
public void Emit(ParticleType type, int amount, Vector2 position, Vector2 positionRange) | ||
{ | ||
for (int i = 0; i < amount; i++) | ||
Emit(type, Calc.Random.Range(position - positionRange, position + positionRange)); | ||
} | ||
|
||
public void Emit(ParticleType type, int amount, Vector2 position, Vector2 positionRange, float direction) | ||
{ | ||
for (int i = 0; i < amount; i++) | ||
Emit(type, Calc.Random.Range(position - positionRange, position + positionRange), direction); | ||
} | ||
|
||
public void Emit(ParticleType type, int amount, Vector2 position, Vector2 positionRange, Color color) | ||
{ | ||
for (int i = 0; i < amount; i++) | ||
Emit(type, Calc.Random.Range(position - positionRange, position + positionRange), color); | ||
} | ||
|
||
public void Emit(ParticleType type, int amount, Vector2 position, Vector2 positionRange, Color color, float direction) | ||
{ | ||
for (int i = 0; i < amount; i++) | ||
Emit(type, Calc.Random.Range(position - positionRange, position + positionRange), color, direction); | ||
} | ||
|
||
public void Emit(ParticleType type, Entity track, int amount, Vector2 position, Vector2 positionRange, float direction) | ||
{ | ||
for (int i = 0; i < amount; i++) | ||
{ | ||
type.Create(ref particles[nextSlot], track, Calc.Random.Range(position - positionRange, position + positionRange), direction, type.Color); | ||
nextSlot = (nextSlot + 1) % particles.Length; | ||
} | ||
} | ||
} | ||
} |
Oops, something went wrong.