GDS Monogame Particle System GDS Monogame Particle System
GDS Particle System for Monogame (Windows) - Originally written for Microsoft XNA (Used in Circuit Commander and other GDS Games)


Sample Code (download here:GDS.Monogame.ParticleSystem.TestProject.zip (Apx. 1MB))

using GDS.Monogame.ParticleSystem;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

namespace TestProject
{
  /// <summary>
  /// This is the main type for your game.
  /// </summary>
  public class Game1 : Game
  {
    GraphicsDeviceManager graphics;
    SpriteBatch spriteBatch;
    ParticleSystemManager ParticleManager = null;
    Texture2D dot;
    Texture2D dot_glow;
    Texture2D flame;
    Texture2D smoke;
    Texture2D background;
    SpriteFont font;
    Matrix globalTransformationMatrix = Matrix.Identity;

    bool disableVSYNC = false;
    public Game1()
    {
      Window.AllowUserResizing = true;
      Window.Title = "GDS.Monogame.ParticleSystem © 2017 GD Software.";
      graphics = new GraphicsDeviceManager(this);
      this.graphics.PreferredBackBufferWidth = 640;
      this.graphics.PreferredBackBufferHeight = 427;
      this.Window.Position = new Point(GraphicsAdapter.DefaultAdapter.CurrentDisplayMode.Width / 2 - 640 / 2, GraphicsAdapter.DefaultAdapter.CurrentDisplayMode.Height / 2 - 427 / 2);
      Content.RootDirectory = "Content";
    }

    /// <summary>
    /// Allows the game to perform any initialization it needs to before starting to run.
    /// This is where it can query for any required services and load any non-graphic
    /// related content.  Calling base.Initialize will enumerate through any components
    /// and initialize them as well.
    /// </summary>
    protected override void Initialize()
    {
      if (disableVSYNC)
      {
        this.IsFixedTimeStep = false;
        graphics.SynchronizeWithVerticalRetrace = false;
        graphics.ApplyChanges();
      }

      base.Initialize();
    }

    /// <summary>
    /// LoadContent will be called once per game and is the place to load
    /// all of your content.
    /// </summary>
    protected override void LoadContent()
    {
      // Create a new SpriteBatch, which can be used to draw textures.
      spriteBatch = new SpriteBatch(GraphicsDevice);

      /*
      LOAD STATIC TEXTURES
      */
      flame = Content.Load<Texture2D>("Textures/flame");
      smoke = Content.Load<Texture2D>("Textures/smoke");
      dot = Content.Load<Texture2D>("Textures/dot");
      dot_glow = Content.Load<Texture2D>("Textures/dot_glow");
      background = Content.Load<Texture2D>("Textures/bg");
      font = Content.Load<SpriteFont>("Fonts/font");
      /*
       SETUP GDS MONOGAME PARTICLE SYSTEM
      */
      this.ParticleManager = new ParticleSystemManager
      {
        new ParticleSystemHost("Smoke",
          
          // SMOKE  (add smoke before flame, to ensure its drawn behind the flame)
          new ParticleSystem(
            10, smoke, 20, 200, 0.1f, 1f, 0.1f, 1.0f, 0.1f, 1.0f, -1f, 1f, 0.1f, 1f, true, new Color[] { Color.Black }, MathHelper.ToRadians(-90), 1, 0, 0.1f, 0.1f, 0)){
            Effects = new System.Collections.Generic.List<object>(){ new fxFlame(50, 50, -90, 30, 500) }},
          
          // FLAME
          new ParticleSystemHost("Flame", new ParticleSystem(
            10, flame, 10, 50, 0.1f, 0.4f, 1f, 100.0f, 1f, 10.0f, 0.1f, 1f, 0.1f, 1f, false, new Color[] { Color.Red, Color.Orange, Color.LightYellow }, MathHelper.ToRadians(-90), 1, 1)){
            Effects = new System.Collections.Generic.List<object>() { new fxFlame(50, 50, -90, 100, 300, 0.1f, 0, 2) } },
          
          // Emitter
          new ParticleSystemHost("Emitter", new ParticleSystem(
            10, dot, 100, 500, 0.1f, 3f, 0.1f, 300.0f, 0.1f, 100.0f, 0.1f, 1.0f, 0.01f, 0.5f, false, Color.White, 1, 0)),
            
          // Spark
          new ParticleSystemHost("Spark", new ParticleSystem(
            10, dot, 2, 10, 0.01f, 0.2f, 0.4f, 200.0f, 0.1f, 100.0f, 0.1f, 1.0f, 0.1f, 5.0f, false, new Color[] { Color.White, Color.Blue }, -1, 1, 1f, 5f,1,0))
      };


      // done

    }

    /// <summary>
    /// UnloadContent will be called once per game and is the place to unload
    /// game-specific content.
    /// </summary>
    protected override void UnloadContent()
    {
      // TODO: Unload any non ContentManager content here
    }

    /// <summary>
    /// Allows the game to run logic such as updating the world,
    /// checking for collisions, gathering input, and playing audio.
    /// </summary>
    /// <param name="gameTime">Provides a snapshot of timing values.</param>
    protected override void Update(GameTime gameTime)
    {
      // tell our particle system to emit from some point
      Vector2 pos = new Vector2(
          (float)GraphicsDevice.PresentationParameters.BackBufferWidth / 2f,
          ((float)GraphicsDevice.PresentationParameters.BackBufferHeight / 100f) * 75f);

      // ADD SMOKE PARTICLES
      this.ParticleManager["Smoke"].ParticleSystem.AddParticles(pos);
      // ADD FLAME PARTICLES
      this.ParticleManager["Flame"].ParticleSystem.AddParticles(pos);

      Vector2 pos2 = new Vector2(50, 50);

      this.ParticleManager["Emitter"].ParticleSystem.AddParticles(pos2);

      this.ParticleManager["Spark"].ParticleSystem.AddParticles(pos2);


      this.ParticleManager.Update(gameTime);

      // dublicate attributes, for more realistic smoke (same direction and power as flame)
      this.ParticleManager["Smoke"].Effects[0] = this.ParticleManager["Flame"].Effects[0];


      base.Update(gameTime);
    }

    float prevFps = 0;
    /// <summary>
    /// This is called when the game should draw itself.
    /// </summary>
    /// <param name="gameTime">Provides a snapshot of timing values.</param>
    protected override void Draw(GameTime gameTime)
    {

      prevFps = MathHelper.Lerp(prevFps, (1000f / (float)gameTime.ElapsedGameTime.TotalMilliseconds), 1f * (float)gameTime.ElapsedGameTime.TotalSeconds);


      // clear device
      GraphicsDevice.Clear(Color.Black);
      spriteBatch.Begin();
      spriteBatch.Draw(background, Vector2.Zero, Color.White);

      string text = "GDS.Monogame.ParticleSystem © 2017 GD Software.";
      Vector2 textSize = font.MeasureString(text);
      spriteBatch.DrawString(font, prevFps.ToString("0.00") + " FPS", new Vector2(45, 200), Color.White);
      spriteBatch.DrawString(font, text, new Vector2((float)(GraphicsDevice.PresentationParameters.BackBufferWidth / 2f - textSize.X / 2f), GraphicsDevice.PresentationParameters.BackBufferHeight - 50f), Color.Yellow);



      spriteBatch.End();
      // draw particle system (globalTransformationMatrix (for 3D sapces, and scaling/moving environment)
      this.ParticleManager.Draw(gameTime, globalTransformationMatrix, this.spriteBatch);

      // base draw
      base.Draw(gameTime);
    }
  }
}

  


How it looks:

GDS Monogame Particle System Demo Project