Particle Animations using Microsoft XNA: Part II

In this article I will be talking much more about Particle Animations.

In the previous article you've seen how to show a particle in XNA. That was a simple application. But this time we will be making a much more detailed animation using 3D models & Particles.

Whats Next?

This sample contains 2 particle effects & a rotating 3D model.

The Red Comet will crush to Earth and it will explode :) Theres no reality but I believe it will be a nice sample to show Particle Animations on demonstration.

Particle Effects:

Red Comet

1.gif

Explosion

2.gif
 
World 3D Model:

3.gif

Lets create the project and see how its done.

4.gif

First of all we need to add some variables:

Model myModel;
float aspectRatio;
Vector3 modelPosition = Vector3.Backward;
float modelRotation = 0.0f;
Vector3 cameraPosition = new Vector3(100, 100, 1500);
int spx, spy;
bool boom;
int a;
Texture2D myTexture;
Vector2 spritePosition = new Vector2(400, 400);
int ani_2;
Texture2D boom_part;

myModel is the Model Object we will be using for 3D Rotating World Model.
modelPosition will help us to store the position infos of the 3d Model.
modelRotation will help us in which speed we wish to rotate it.Lesser values will make it rotate slower.
Spx & Spy are the position values of SpriteBatch which will be used for positioning Particles.
Boom is the boolean value which query whether red comet has crushed the World or not. 
"a" variable is the counter as you will know from the previous sample.
spritePosition is the variable we use for storing the particles' positions.
Ani_2 is the counter variable for Explosion Particle.

boom_part is the explosion particle.

Update Game1 as:

public Game1()
{
  graphics = new GraphicsDeviceManager(this);
  Content.RootDirectory = "Content";
  Window.Title = "Boom!";

We have added a Title to the XNA Window named "Boom!" 

Update LoadContent as:

protected override void LoadContent()
{
    spriteBatch = new SpriteBatch(GraphicsDevice);
    myModel = Content.Load<Model>("Model\\world");
    myTexture = Content.Load<Texture2D>("particles//Comet//comet_1");
    boom_part = Content.Load<Texture2D>("particles//Explosion//explosion_1");
    aspectRatio = graphics.GraphicsDevice.Viewport.AspectRatio;
}

We have added the start values of 3d model and particle textures.


Update the "Update" function as:

protected override void Update(GameTime gameTime)
{
    modelRotation += (float)gameTime.ElapsedGameTime.TotalMilliseconds *   
                                 MathHelper.ToRadians(0.02f);
    KeyboardState keystat = Keyboard.GetState();
    if (keystat.IsKeyDown(Keys.Up))
    {
        spx += 1;
        spy += 1;
    }
    else if (keystat.IsKeyDown(Keys.Down))
    {
        spx -= 1;
        spy -= 1;
    }
    if (boom)
    {
        ani_2++;
        if (ani_2 == 50)
        {
            ani_2 = 49;
        }
        else
        {
            boom_part = Content.Load<Texture2D>("particles//Explosion//explosion_" + ani_2);
        }
    }
    a++;
    if (a == 50)
    {
        a = 15;
    }
    else
    {
        myTexture = Content.Load<Texture2D>("particles//Comet//comet_" + a);
    }
    if (spx > 75)
    {
        boom = true;
    }
    base.Update(gameTime);
}

If we press "UP" key the red comet will be going enroute World. And Down key will be the reverse one.

And if boom is true which means if red comet crushed then world will explode.

If spx value is bigger than 75 then it means it will crush to the World.

This is a simple sample to demonstrate what we can do with Particles so truth be told I have made it as easy as possible. You can use Collision Detection if you want. But I didnt need it in this sample.

And finally Update our Draw Function as:

protected override void Draw(GameTime gameTime)
{
    GraphicsDevice.Clear(Color.Black);
    Matrix[] transforms = new Matrix[myModel.Bones.Count];
    myModel.CopyAbsoluteBoneTransformsTo(transforms);
    if (!boom)
    {
        foreach (ModelMesh mesh in myModel.Meshes)
        {
            foreach (BasicEffect effect in mesh.Effects)
            {
                effect.EnableDefaultLighting();
                effect.World = transforms[mesh.ParentBone.Index] *
                                     Matrix.CreateRotationY(modelRotation)
                                      * Matrix.CreateTranslation(modelPosition);
                effect.View = Matrix.CreateLookAt(cameraPosition,
                            Vector3.Zero, Vector3.Up);
                effect.PreferPerPixelLighting = true;
                effect.Projection = Matrix.CreatePerspectiveFieldOfView(
                                          MathHelper.ToRadians(35.0f), aspectRatio,
                                          1.0f, 10000.0f);
            }
            mesh.Draw();
        }
        spriteBatch.Begin(SpriteBlendMode.AlphaBlend);
        spriteBatch.Draw(myTexture, new Rectangle(spx, spy, 300, 300), Color.White);
        spriteBatch.End();
    }
    else
    {
        spriteBatch.Begin(SpriteBlendMode.AlphaBlend);
        spriteBatch.Draw(boom_part, new Rectangle(spx + 175, spy + 50, 300, 300), Color.White);
        spriteBatch.End();
    }
    base.Draw(gameTime);
}  

This code whows a simple model loading. While boom is false we tell 3D World to rotate and red comet to continue flying.

If boom is true then the red comet and 3D World will be visible instead explosion particle will show itself.

Lets run the sample and see what happens.

5.gif

By pressing Up Key the red comet will come closer to the world.and when came to near, it will explode as shown below:

6.gif

Yeap Red Comet crushed and we all died. We're in heaven right now. Nice joke, isn't it.

This sample showed that using 2D Particle Animations you can perfect your game and insert action which will keep the player to continue play your game.

I hope this mini article-sample demonstration helped you and opened your mind to insert nice effects in your game project.


Similar Articles