source: 2010/23/sijoseha/alpha/Effects/ParticleSystem.cs @ 10335

Revision 833, 7.1 KB checked in by sijoseha, 9 years ago (diff)

Building up.
We have something on the screen already!

Line 
1using System;
2using System.Collections.Generic;
3using System.Linq;
4using Microsoft.Xna.Framework;
5using Microsoft.Xna.Framework.Audio;
6using Microsoft.Xna.Framework.Content;
7using Microsoft.Xna.Framework.GamerServices;
8using Microsoft.Xna.Framework.Graphics;
9using Microsoft.Xna.Framework.Input;
10using Microsoft.Xna.Framework.Media;
11using Microsoft.Xna.Framework.Net;
12using Microsoft.Xna.Framework.Storage;
13
14namespace Effects
15{
16    public abstract class ParticleSystem : DrawableGameComponent
17    {
18        // Gives us Content and SpriteBatch
19        private ParticleGame game;
20
21        // Random
22        Random random = new Random();
23
24        // Array for particles in one effect
25        Particle[] particles;
26
27        // Queue for free particles
28        Queue<Particle> freeParticles;
29
30        /// <summary>
31        /// There are variables that need to be set by subclasses
32        /// </summary>
33        #region Subclass variables
34        protected Vector2 position;
35
36        protected String textureName;
37
38        protected String innerTextureName;
39        protected String outerTextureName;
40
41        protected float minScale;
42        protected float maxScale;
43
44        protected float rotation;
45
46        protected Vector2 origin;
47
48        protected float minVelocity;
49        protected float maxVelocity;
50
51        protected float minLifetime;
52        protected float maxLifetime;
53
54        protected float rotationSpeed;
55
56        protected int maxAmountOfParticles;
57
58        #endregion
59
60        // Does the effect use single texture or dual texture
61        protected enum TextureType
62        {
63            Single,
64            Dual
65        };
66
67        // Does the effect use single or dual texture
68        protected TextureType textureType;
69
70        // Textures for effect
71        private Texture2D texture, innerTexture, outerTexture;
72
73        // Origin of textures
74        private Vector2 textureOrigin;
75
76        // Maximum amount of particles the effect can use
77        /*private int maxAmountOfParticles;
78        public int MaxAmountOfParticles
79        {
80            get { return maxAmountOfParticles; }
81            set { maxAmountOfParticles = value; }
82        }*/
83
84        /// <summary>
85        /// Constructor
86        /// </summary>
87        /// <param name="game">Game where the effect is used</param>
88        /// <param name="position">Position where the effect is displayed</param>
89        public ParticleSystem(ParticleGame game)
90            : base(game)
91        {
92            this.game = game;
93        }
94
95        /// <summary>
96        /// Initializes the particle system
97        /// </summary>
98        public override void Initialize()
99        {
100            InitializeParticles();
101
102            particles = new Particle[maxAmountOfParticles];
103            freeParticles = new Queue<Particle>(maxAmountOfParticles);
104            for (int i = 0; i < maxAmountOfParticles; i++)
105            {
106                particles[i] = new Particle();
107                freeParticles.Enqueue(particles[i]);
108            }
109            base.Initialize();
110        }
111
112        /// <summary>
113        /// Method that describes variables for the effect
114        /// Must be called by subclasses
115        /// </summary>
116        protected abstract void InitializeParticles();
117
118        /// <summary>
119        /// Loads textures for the effect and calculates origins
120        /// </summary>
121        protected override void LoadContent()
122        {
123            if (textureType == TextureType.Single)
124            {
125                texture = game.Content.Load<Texture2D>(textureName.ToString());
126                textureOrigin.X = texture.Width / 2;
127                textureOrigin.Y = texture.Height / 2;
128            }
129            if (textureType == TextureType.Dual)
130            {
131                innerTexture = game.Content.Load<Texture2D>(innerTextureName.ToString());
132                outerTexture = game.Content.Load<Texture2D>(outerTextureName.ToString());
133                textureOrigin.X = outerTexture.Width / 2;
134                textureOrigin.Y = outerTexture.Height / 2;
135            }
136
137            base.LoadContent();
138        }
139
140        public void AddEffect(Vector2 where)
141        {
142            int numParticles = 10;
143            for (int i = 0; i < numParticles && freeParticles.Count > 0; i++)
144            {
145                Particle p = freeParticles.Dequeue();
146                InitializeParticle(p, where);
147            }
148        }
149
150        protected virtual Vector2 GiveRandomDirection()
151        {
152            float angle = (float)random.NextDouble() * MathHelper.TwoPi;
153            return new Vector2((float)Math.Cos(angle), (float)Math.Sin(angle));
154        }
155
156        /// <summary>
157        /// Initializes single particle in the effect
158        /// </summary>
159        /// <param name="p">Particle to be initialize</param>
160        /// <param name="position">Position where to initialize</param>
161        protected virtual void InitializeParticle(Particle p, Vector2 position)
162        {
163            Vector2 direction = GiveRandomDirection();
164
165            float scale = 1.0f;
166            float rotation = 1.0f;
167            float velocity = maxVelocity;
168            float lifetime = 1.0f;
169
170            p.Initialize(position, scale, rotation, velocity * direction, lifetime);
171        }
172
173        /// <summary>
174        /// Called when particle system is updated
175        /// </summary>
176        /// <param name="gameTime">Gametime</param>
177        public override void Update(GameTime gameTime)
178        {
179            float time = (float)gameTime.ElapsedGameTime.TotalSeconds;
180
181            foreach (Particle p in particles)
182            {
183                if (p.Alive)
184                {
185                    p.Update(time);
186
187                    if (!p.Alive)
188                    {
189                        freeParticles.Enqueue(p);
190                    }
191                }
192            }
193
194            base.Update(gameTime);
195        }
196
197        /// <summary>
198        /// Called when particle system needs to be drawn
199        /// </summary>
200        /// <param name="gameTime">Gametime</param>
201        public override void Draw(GameTime gameTime)
202        {
203            game.SpriteBatch.Begin();
204            foreach (Particle p in particles)
205            {
206                if (!p.Alive)
207                {
208                    continue;
209                }
210                if (textureType == TextureType.Single)
211                {
212                    game.SpriteBatch.Draw(texture, p.Position, null, Color.White, p.Rotation, textureOrigin, p.Scale, SpriteEffects.None, 1.0f);
213                }
214                if (textureType == TextureType.Dual)
215                {
216                    game.SpriteBatch.Draw(outerTexture, p.Position, null, Color.White, p.Rotation, textureOrigin, p.Scale, SpriteEffects.None, 1.0f);
217                    game.SpriteBatch.Draw(innerTexture, p.Position, null, Color.White, p.Rotation, textureOrigin, p.Scale*0.6f, SpriteEffects.None, 1.0f);
218                }
219            }
220            game.SpriteBatch.End();
221            base.Draw(gameTime);
222        }
223    }
224}
Note: See TracBrowser for help on using the repository browser.