Jypeli  9
The simple game programming library
ParticleSystem.cs
Siirry tämän tiedoston dokumentaatioon.
1 using System;
2 using System.Collections.Generic;
4 using Microsoft.Xna.Framework.Graphics;
5 
6 namespace Jypeli.Effects
7 {
8  public enum BlendMode
9  {
10  Alpha,
11  Additive
12  }
13 
14 
18  public class ParticleSystem : GameObject
19  {
20  private Random random = new Random();
21 
22  // Lista efektin partikkeleille
23  private LinkedList<Particle> particles;
24 
25  // Jono efektin vapaille partikkeleille
26  private Queue<Particle> freeParticles;
27 
31  public Image ParticleImage { get; set; }
32 
36  public Image OuterParticleImage { get; set; }
37 
38  // Perivien luokkien täytyy määrittää nämä muuttujat
39  #region Subclass variables
40 
44  public double MinScale { get; set; }
45 
49  public double MaxScale { get; set; }
50 
54  public double ScaleAmount { get; set; }
55 
59  public double MinVelocity { get; set; }
63  public double MaxVelocity { get; set; }
64 
68  public double MinLifetime { get; set; }
69 
73  public double MaxLifetime { get; set; }
74 
78  public double MinAcceleration { get; set; }
79 
83  public double MaxAcceleration { get; set; }
84 
88  public double MinRotationSpeed { get; set; }
89 
93  public double MaxRotationSpeed { get; set; }
94 
98  public double MinRotation { get; set; }
99 
103  public double MaxRotation { get; set; }
104 
108  public double AlphaAmount { get; set; }
109 
110  #endregion
111 
112  public BlendMode BlendMode { get; set; }
113 
117  public Boolean IgnoreWind { get; set; }
118 
119  private Boolean visible = true;
120  private Boolean fadeIn = false;
121  private Boolean fadeOut = false;
122  private double originalAlpha = 1.0;
123  private double fadeTime = 0.0;
124  private double fadeTimePassed = 0.0;
125 
130  public void FadeIn(double timeInSeconds)
131  {
132  if (!visible)
133  {
134  fadeTimePassed = 0.0;
135  fadeIn = true;
136  fadeTime = timeInSeconds;
137  }
138  }
139 
144  public void FadeOut(double TimeInSeconds)
145  {
146  if (visible)
147  {
149  fadeTimePassed = 0.0;
150  fadeOut = true;
151  fadeTime = TimeInSeconds;
152  }
153  }
159  public ParticleSystem(Image particleImage, int maxAmountOfParticles)
160  : base(0, 0)
161  {
162  this.ParticleImage = particleImage;
163  AlphaAmount = 1.0;
164  IgnoreWind = false;
165  BlendMode = BlendMode.Alpha;
166 
167  IsUpdated = true;
169 
170  particles = new LinkedList<Particle>();
171  freeParticles = new Queue<Particle>(maxAmountOfParticles);
172  for (int i = 0; i < maxAmountOfParticles; i++)
173  {
174  freeParticles.Enqueue(new Particle());
175  }
176  }
177 
182  protected virtual void InitializeParticles()
183  {
184  }
185 
192  public void AddEffect(double x, double y, int numberOfParticles)
193  {
194  AddEffect(new Vector(x, y), numberOfParticles);
195  }
196 
197  public void AddEffect(Vector position, Angle angle, int numberOfParticles)
198  {
199  for (int i = 0; i < numberOfParticles && freeParticles.Count > 0; i++)
200  {
201  Particle p = freeParticles.Dequeue();
202  particles.AddLast(p);
203  InitializeParticle(p, position, angle);
204  }
205  }
206 
212  public void AddEffect(Vector position, int numberOfParticles)
213  {
214  for (int i = 0; i < numberOfParticles && freeParticles.Count > 0; i++)
215  {
216  Particle p = freeParticles.Dequeue();
217  particles.AddLast(p);
218  InitializeParticle(p, position);
219  }
220  }
221 
226  protected virtual Vector GiveRandomDirection()
227  {
228  double angle = random.NextDouble() * MathHelper.TwoPi;
229  return new Vector(Math.Cos(angle), Math.Sin(angle));
230  }
231 
237  protected virtual void InitializeParticle(Particle p, Vector position)
238  {
239  Vector direction = GiveRandomDirection();
240 
241  double scale = RandomGen.NextDouble(MinScale, MaxScale);
242  double rotation = RandomGen.NextDouble(MinRotation, MaxRotation);
243  double velocity = RandomGen.NextDouble(MinVelocity, MaxVelocity);
244  double lifetime = RandomGen.NextDouble(MinLifetime, MaxLifetime);
245  double acceleration = RandomGen.NextDouble(MinAcceleration, MaxAcceleration);
246  double rotationSpeed = RandomGen.NextDouble(MinRotationSpeed, MaxRotationSpeed);
247 
248  p.Initialize(position, scale, rotation, rotationSpeed, velocity * direction, acceleration * direction, lifetime);
249  }
250 
251  protected virtual void InitializeParticle(Particle p, Vector position, Angle angle)
252  {
253  Vector direction = GiveRandomDirection();
254 
255  double rotation = angle.Degrees;
256  double scale = RandomGen.NextDouble(MinScale, MaxScale);
257  double velocity = RandomGen.NextDouble(MinVelocity, MaxVelocity);
258  double lifetime = RandomGen.NextDouble(MinLifetime, MaxLifetime);
259  double acceleration = RandomGen.NextDouble(MinAcceleration, MaxAcceleration);
260  double rotationSpeed = RandomGen.NextDouble(MinRotationSpeed, MaxRotationSpeed);
261 
262  p.Initialize(position, scale, rotation, rotationSpeed, velocity * direction, acceleration * direction, lifetime);
263  }
264 
269  public override void Update(Time time)
270  {
271  double t = time.SinceLastUpdate.TotalSeconds;
272 
273  LinkedListNode<Particle> node = particles.First;
274  while (node != null)
275  {
276  Particle p = node.Value;
277  if (p.Alive)
278  {
279  p.Update(t);
280  node = node.Next;
281  }
282  else
283  {
284  freeParticles.Enqueue(p);
285  LinkedListNode<Particle> previous = node;
286  node = node.Next;
287  particles.Remove(previous);
288  }
289  }
290  if (fadeOut)
291  {
293  fadeTimePassed += t;
294  if (fadeTime <= fadeTimePassed)
295  {
296  AlphaAmount = 0.0;
297  fadeOut = false;
298  visible = false;
299  }
300  }
301  if (fadeIn)
302  {
304  fadeTimePassed += t;
305  if (fadeTime <= fadeTimePassed)
306  {
308  fadeIn = false;
309  visible = true;
310  }
311  }
312 
313  base.Update(time);
314  }
315 
316 
317  static readonly Vector2 textureTopLeft = new Vector2(0.0f, 0.0f);
318  static readonly Vector2 textureBottomLeft = new Vector2(0.0f, 1.0f);
319  static readonly Vector2 textureTopRight = new Vector2(1.0f, 0.0f);
320  static readonly Vector2 textureBottomRight = new Vector2(1.0f, 1.0f);
321 
322  static readonly Vector3 topLeft = new Vector3(-0.5f, 0.5f, 0);
323  static readonly Vector3 bottomLeft = new Vector3(-0.5f, -0.5f, 0);
324  static readonly Vector3 topRight = new Vector3(0.5f, 0.5f, 0);
325  static readonly Vector3 bottomRight = new Vector3(0.5f, -0.5f, 0);
326 
327  static readonly VertexPositionTexture[] vertices =
328  {
329  // Triangle 1
330  new VertexPositionTexture(topLeft, textureTopLeft),
331  new VertexPositionTexture(bottomLeft, textureBottomLeft),
332  new VertexPositionTexture(topRight, textureTopRight),
333 
334  // Triangle 2
335  new VertexPositionTexture(bottomLeft, textureBottomLeft),
336  new VertexPositionTexture(bottomRight, textureBottomRight),
337  new VertexPositionTexture(topRight, textureTopRight),
338  };
339 
340  private static BlendState ToXnaBlendState(BlendMode mode)
341  {
342  switch (mode)
343  {
344  case BlendMode.Alpha:
345  return BlendState.AlphaBlend;
346  case BlendMode.Additive:
347  return BlendState.Additive;
348  default:
349  return BlendState.AlphaBlend;
350  }
351  }
352 
353  internal void Draw(Matrix worldMatrix)
354  {
355  var device = Game.GraphicsDevice;
356  var effect = Graphics.BasicTextureEffect;
357 
358  Texture2D texture = ParticleImage.XNATexture;
359 
360  device.RasterizerState = RasterizerState.CullClockwise;
361  device.SamplerStates[0] = SamplerState.LinearClamp;
362  device.BlendState = ToXnaBlendState(BlendMode);
363 
364  effect.Texture = texture;
365  effect.CurrentTechnique.Passes[0].Apply();
366 
367  if (OuterParticleImage == null)
368  {
369  foreach (Particle p in particles)
370  {
371  double nTime = p.Lifetime.TotalMilliseconds / p.MaxLifetime.TotalMilliseconds;
372  double alpha = 4 * nTime * (1 - nTime) * AlphaAmount;
373  float scale = (float)(p.Scale * (.75f + .25f * nTime * ScaleAmount));
374 
375  Matrix matrix =
376  Matrix.CreateScale(scale * texture.Width / texture.Height, scale, 1f)
377  * Matrix.CreateRotationZ((float)p.Rotation)
378  * Matrix.CreateTranslation((float)p.Position.X, (float)p.Position.Y, 0f)
379  * worldMatrix
380  ;
381 
382  effect.Alpha = (float)alpha;
383  effect.World = matrix;
384  effect.CurrentTechnique.Passes[0].Apply();
385 
386  device.DrawUserPrimitives<VertexPositionTexture>(PrimitiveType.TriangleList, vertices, 0, 2);
387  }
388  }
389  else
390  {
391  Texture2D outerTexture = OuterParticleImage.XNATexture;
392 
393  foreach (Particle p in particles)
394  {
395  double nTime = p.Lifetime.TotalMilliseconds / p.MaxLifetime.TotalMilliseconds;
396  double alpha = 4 * nTime * (1 - nTime) * AlphaAmount;
397  float scale = (float)(p.Scale * (.75f + .25f * nTime * ScaleAmount));
398 
399  Matrix matrix =
400  Matrix.CreateScale(scale, scale, 1f)
401  * Matrix.CreateRotationZ((float)p.Rotation)
402  * Matrix.CreateTranslation((float)p.Position.X, (float)p.Position.Y, 0f)
403  * worldMatrix
404  ;
405  Matrix matrix2 =
406  Matrix.CreateScale(0.65f, 0.65f, 1f)
407  * matrix;
408 
409  effect.Texture = texture;
410  effect.Alpha = (float)alpha;
411  effect.World = matrix;
412  effect.CurrentTechnique.Passes[0].Apply();
413 
414  device.DrawUserPrimitives<VertexPositionTexture>(PrimitiveType.TriangleList, vertices, 0, 2);
415 
416  effect.Texture = outerTexture;
417  effect.World = matrix2;
418  effect.CurrentTechnique.Passes[0].Apply();
419 
420  device.DrawUserPrimitives<VertexPositionTexture>(PrimitiveType.TriangleList, vertices, 0, 2);
421  }
422  }
423  }
424  }
425 }
Jypeli.Effects.ParticleSystem.MaxVelocity
double MaxVelocity
Suurin nopeus joka efektin partikkelilla voi olla
Definition: ParticleSystem.cs:63
Jypeli.Effects.ParticleSystem.topLeft
static readonly Vector3 topLeft
Definition: ParticleSystem.cs:322
Jypeli.Effects.Particle.Rotation
double Rotation
Partikkelin kierto
Definition: Particle.cs:43
Jypeli.Matrix
Microsoft.Xna.Framework.Matrix Matrix
Definition: Mouse.cs:36
Microsoft.Xna
Definition: JypeliContentManager.cs:6
Jypeli.Effects.ParticleSystem.MinRotation
double MinRotation
Pienin kierre mikä efektin partikkelilla voi olla
Definition: ParticleSystem.cs:98
Jypeli.Effects.ParticleSystem
Järjestelmä partikkelien käsittelyyn
Definition: ParticleSystem.cs:19
Jypeli.Effects.ParticleSystem.particles
LinkedList< Particle > particles
Definition: ParticleSystem.cs:23
Jypeli.Effects.ParticleSystem.fadeOut
Boolean fadeOut
Definition: ParticleSystem.cs:121
Jypeli.Effects.ParticleSystem.textureTopRight
static readonly Vector2 textureTopRight
Definition: ParticleSystem.cs:319
Jypeli.Effects.Particle.Initialize
void Initialize(Vector position, double scale, double rotation, double rotationSpeed, Vector velocity, Vector acceleration, double lifetime)
Alusta partikkeli
Definition: Particle.cs:112
Jypeli.Effects.ParticleSystem.AddEffect
void AddEffect(Vector position, Angle angle, int numberOfParticles)
Definition: ParticleSystem.cs:197
Jypeli.Effects.ParticleSystem.fadeIn
Boolean fadeIn
Definition: ParticleSystem.cs:120
Jypeli.Vector.X
double X
Definition: Vector.cs:312
Jypeli.Effects.ParticleSystem.MinVelocity
double MinVelocity
Pienin nopeus joka efektin partikkelilla voi olla
Definition: ParticleSystem.cs:59
Microsoft
Definition: JypeliContentManager.cs:6
Microsoft.Xna.Framework
Definition: JypeliContentManager.cs:6
Jypeli.Effects.Particle.Lifetime
TimeSpan Lifetime
Partikkelin tämän hetkinen ikä
Definition: Particle.cs:96
Jypeli.Effects.ParticleSystem.AlphaAmount
double AlphaAmount
Efektin läpinäkyvyyskerroin (0.0-1.0)
Definition: ParticleSystem.cs:108
Jypeli.Effects.ParticleSystem.ParticleImage
Image ParticleImage
Yksittäisen partikkelin kuva.
Definition: ParticleSystem.cs:31
Jypeli.Effects.ParticleSystem.random
Random random
Definition: ParticleSystem.cs:20
Jypeli.Effects.ParticleSystem.originalAlpha
double originalAlpha
Definition: ParticleSystem.cs:122
Jypeli.Effects.ParticleSystem.visible
Boolean visible
Definition: ParticleSystem.cs:119
Jypeli.Effects.ParticleSystem.GiveRandomDirection
virtual Vector GiveRandomDirection()
Antaa satunnaisen suunnan
Definition: ParticleSystem.cs:226
Jypeli.Image.XNATexture
Texture2D XNATexture
Definition: Image.cs:71
Jypeli.Effects.ParticleSystem.MaxScale
double MaxScale
Suurin skaalaus joka efektin partikkeleilla voi olla
Definition: ParticleSystem.cs:49
Jypeli.Effects.ParticleSystem.MaxRotationSpeed
double MaxRotationSpeed
Suurin pyörimisnopeus joka efektin partikkelilla voi olla
Definition: ParticleSystem.cs:93
Jypeli.Effects.ParticleSystem.OuterParticleImage
Image OuterParticleImage
Partikkelin toissijainen kuva. Jos null niin käytetään vain yhtä kuvaa.
Definition: ParticleSystem.cs:36
Jypeli.RandomGen
Satunnaisgeneraattori. Luo satunnaisia arvoja, mm. lukuja, vektoreita sekä kulmia.
Definition: RandomGen.cs:39
Jypeli.Effects.ParticleSystem.fadeTime
double fadeTime
Definition: ParticleSystem.cs:123
Jypeli.Effects.ParticleSystem.AddEffect
void AddEffect(Vector position, int numberOfParticles)
Lisää efektin kentälle
Definition: ParticleSystem.cs:212
Jypeli.Effects.ParticleSystem.textureBottomLeft
static readonly Vector2 textureBottomLeft
Definition: ParticleSystem.cs:318
Jypeli.Effects.ParticleSystem.textureBottomRight
static readonly Vector2 textureBottomRight
Definition: ParticleSystem.cs:320
Jypeli.Effects.ParticleSystem.vertices
static readonly VertexPositionTexture[] vertices
Definition: ParticleSystem.cs:327
Jypeli.Effects.ParticleSystem.bottomLeft
static readonly Vector3 bottomLeft
Definition: ParticleSystem.cs:323
Jypeli.Time
Sisältää tiedon ajasta, joka on kulunut pelin alusta ja viime päivityksestä.
Definition: Time.cs:14
Jypeli.Effects.ParticleSystem.InitializeParticles
virtual void InitializeParticles()
Metodi joka asettaa partikkeleille attribuutit Täytyy kutsua perityistä luokista
Definition: ParticleSystem.cs:182
Jypeli.Graphics.BasicTextureEffect
static BasicEffect BasicTextureEffect
Definition: Graphics.cs:37
Jypeli.Effects.ParticleSystem.MaxAcceleration
double MaxAcceleration
Suurin kiihtyvyys joka efektin partikkelilla voi olla
Definition: ParticleSystem.cs:83
Jypeli.Effects.ParticleSystem.IgnoreWind
Boolean IgnoreWind
Vaikuttaako efektiin tuuli
Definition: ParticleSystem.cs:117
Jypeli.Effects.BlendMode.Alpha
@ Alpha
Jypeli.Effects.BlendMode
BlendMode
Definition: ParticleSystem.cs:9
Jypeli.Effects.ParticleSystem.Draw
void Draw(Matrix worldMatrix)
Definition: ParticleSystem.cs:353
Jypeli.Time.SinceLastUpdate
TimeSpan SinceLastUpdate
Aika joka on kulunut viime päivityksestä.
Definition: Time.cs:24
Jypeli.Effects.Particle
Partikkeli
Definition: Particle.cs:9
Jypeli.Effects.ParticleSystem.textureTopLeft
static readonly Vector2 textureTopLeft
Definition: ParticleSystem.cs:317
Jypeli.Effects.ParticleSystem.FadeIn
void FadeIn(double timeInSeconds)
Efekti tulee näkyviin tietyn sekuntimäärän aikana
Definition: ParticleSystem.cs:130
Jypeli.Effects.ParticleSystem.Update
override void Update(Time time)
Kutsutaan kun luokka päivitetään
Definition: ParticleSystem.cs:269
Jypeli.Effects.ParticleSystem.MaxRotation
double MaxRotation
Suurin kierre mikä efektin partikkelilla voi olla
Definition: ParticleSystem.cs:103
Jypeli.Effects.Particle.Alive
bool Alive
Onko partikkelin "elossa", eli päivitetäänkö ja piirretäänkö se
Definition: Particle.cs:79
Jypeli.Effects.ParticleSystem.MinRotationSpeed
double MinRotationSpeed
Pienin pyörimisnopeus joka efektin partikkelilla voi olla
Definition: ParticleSystem.cs:88
Jypeli.Effects.ParticleSystem.InitializeParticle
virtual void InitializeParticle(Particle p, Vector position, Angle angle)
Definition: ParticleSystem.cs:251
Jypeli.Effects.ParticleSystem.MinScale
double MinScale
Pienin skaalaus joka efektin partikkeleilla voi olla
Definition: ParticleSystem.cs:44
Jypeli.Effects.ParticleSystem.ParticleSystem
ParticleSystem(Image particleImage, int maxAmountOfParticles)
Muodostaja
Definition: ParticleSystem.cs:159
Jypeli.Effects.ParticleSystem.FadeOut
void FadeOut(double TimeInSeconds)
Efekti hiipuu näkyvistä tietyn sekuntimäärän aikana
Definition: ParticleSystem.cs:144
Jypeli.Effects.Particle.Position
Vector Position
Partikkelin sijainti
Definition: Particle.cs:25
Jypeli.Graphics
Contains graphics resources.
Definition: Graphics.cs:36
Jypeli.RandomGen.NextDouble
static double NextDouble(double min, double max)
Palauttaa satunnaisen liukuluvun parametrien
Definition: RandomGen.cs:70
Jypeli.Effects.ParticleSystem.fadeTimePassed
double fadeTimePassed
Definition: ParticleSystem.cs:124
Jypeli.Image
Kuva.
Definition: Image.cs:29
Jypeli.Effects.ParticleSystem.bottomRight
static readonly Vector3 bottomRight
Definition: ParticleSystem.cs:325
Jypeli.Effects.ParticleSystem.MinAcceleration
double MinAcceleration
Pienin kiihtyvyys joka efektin partikkelilla voi olla
Definition: ParticleSystem.cs:78
Jypeli.Vector
2D-vektori.
Definition: Vector.cs:59
System
Definition: CFFauxAttributes.cs:29
Jypeli.Effects.Particle.MaxLifetime
TimeSpan MaxLifetime
Partikkelin elinikä
Definition: Particle.cs:87
Jypeli.Effects
Definition: ExplosionSystem.cs:4
Jypeli.Effects.ParticleSystem.MaxLifetime
double MaxLifetime
Efektin partikkelin pisin mahdollinen elinaika
Definition: ParticleSystem.cs:73
Jypeli.Effects.ParticleSystem.ToXnaBlendState
static BlendState ToXnaBlendState(BlendMode mode)
Definition: ParticleSystem.cs:340
Jypeli.Effects.Particle.Update
void Update(double time)
Päivittää partikkelin sijannin, nopeuden ja kierron
Definition: Particle.cs:131
Jypeli.GameObject
Pelialueella liikkuva olio. Käytä fysiikkapeleissä PhysicsObject-olioita.
Definition: Appearance.cs:34
Jypeli.Game.GraphicsDevice
static new GraphicsDevice GraphicsDevice
XNA:n grafiikkakortti.
Definition: Graphics.cs:49
Jypeli.Angle.Degrees
double Degrees
Palauttaa tai asettaa kulman asteina.
Definition: Angle.cs:69
Jypeli.Effects.ParticleSystem.freeParticles
Queue< Particle > freeParticles
Definition: ParticleSystem.cs:26
Jypeli.Effects.ParticleSystem.MinLifetime
double MinLifetime
Efektin partikkelin lyhin mahdollinen elinaika
Definition: ParticleSystem.cs:68
Jypeli.Effects.Particle.Scale
double Scale
Partikkelin skaalaus
Definition: Particle.cs:34
Jypeli.Effects.ParticleSystem.ScaleAmount
double ScaleAmount
Määrä jonka partikkeli skaalautuu päivityksessä
Definition: ParticleSystem.cs:54
Jypeli.Game
Definition: Content.cs:46
Jypeli.Effects.ParticleSystem.topRight
static readonly Vector3 topRight
Definition: ParticleSystem.cs:324
Jypeli.Vector.Y
double Y
Definition: Vector.cs:313
Jypeli.Effects.ParticleSystem.AddEffect
void AddEffect(double x, double y, int numberOfParticles)
Lisää efektin kentälle
Definition: ParticleSystem.cs:192
Jypeli.Angle
Suuntakulma (rajoitettu -180 ja 180 asteen välille) asteina ja radiaaneina. Tietoja kulmasta: http://...
Definition: Angle.cs:40
Jypeli.Effects.ParticleSystem.InitializeParticle
virtual void InitializeParticle(Particle p, Vector position)
Alustaa yhden partikkelin
Definition: ParticleSystem.cs:237