Intermission #7 / 2–Bring on the Fire

2D,XNA,Game DevelopmentIn the last post we set the groundwork with the particle system itself.  Now we can move on to making use of this and adding / customising our effects.

This post will be keenly followed by another post about monitoring the performance of your game.  I hadn’t originally planned on it but since I hit problems when applying the particle effects (completely my own fault but a good lesson to learn), I felt it was wise to impart some of this experience to you.

After that we’ll roll up this phase of intermissions with an update to the Windows Phone 7 project and add all the extra bits (in their WP7 flavour) to that project (cannot wait to run everything from there come XNA 4 full release).

Then back the the tutorial series itself by adding some sound!!

As usual all the code for this section can be found here on codeplex.

 

Source updated for Final combined update project for GS 4.0 project here on Codeplex (Windows and WP7)


 

The aims of our fireball effect

Below is a diagram of what we are aiming for with our replacement fireball effect, a bit more snazzy than our original sprite:

image

We need the emitter to be thrown up spewing out fire as it does and trailed with a smoke plume to give it an extra edge.  We could just launch out particles together from our trooper for the effect but we would loose cohesion from our fireball and loose a level of control should we wish to add similar effects for other weapons.

 


 

Making use of the particle framework

Below is a diagram of the framework we have setup:

image

From here you can see our standard particle system framework.  Within our framework we will define several emitter effect definitions based on the emitter control template.  This gives us a wide array of capabilities and options for setting up our effects, we can implement either:

    Static Controlled effect

Where the game controls how the effect is generated and updated, including when new particles are generated, this is what is used in the CC particle sample.

    Self sustaining effect

Where an effect is launched and generates a pattern of particles but the game still controls the emitter.  Which is what we will use in this tutorial

    Self controlled effect

In this the game initiates the effect but after that has no direct control, the emitter is completely self controlled.  Bit like a fire out of control (if you could program real fire)

So lets get on and get this started.


Finishing up from the last episode

First we will return to the Particle Manager add add the last few parts to make the Particle Engine functional.

Back in the ParticleManager.cs class, first we need the pool for the emitters and a place to store the textures we intend to use (this enables use to re-use textures across emitters without consuming more memory)

Add the following to the beginning of the Particle Manager:

Next we need to update the initialise function to setup our manager:

There is nothing to do in the Load Resources or Unload Resources for now (since textures are added as individual emitters are created, you might want to change this to see what improvements it can make, but remember by moving it here you loose a fair amount of flexibility)

The main work horses of the manager are the Update and Draw loops, in the update loop below:

Here we simply loop through each emitter and update it (if it is active).  If an emitter becomes inactive after it’s update, we then remove it from the pool and free up a slot.

The Draw loop is similar except it does al the draw work in one place:

Here we reuse the SpriteBatch from the main game class setting the corresponding Sprite Blend mode according to the Emitter (so we can use both additive and alpha blended effects (more on that when we use this).  The rest of the code is well commented (from the original MS sample) were we use the particles lifetime to adjust the alpha part of the particle (making if fade out as it dies) and the scale (to make the particle grow as it dies).

Finally we draw each particle to the screen using the texture from the manager according to the specified texture in the emitter.

To finish off the updates to the manager we add a few helper functions that just make life a bit easier:

 

 

Here we just expose the method off adding a new emitter to the manager and a function to manage the texture library maintained by the Particle Manager.

 


On with the show, the first effect

To make it easier to distinguish between the Emitter template and our new effects, first setup a new class in the engine folder called “ParticleEmitters.cs” and then add the following code for the effect:

I’ve added the complete code for this effect, so just replace the generated class (renamed the namespace, added using statements for XNA and removed the default class name).

The implementation is quite simple, we have created a unique effect on top of the template and included 3 overloads:

    Update to Initialise Constants (Mandatory)

This is the only mandatory requirement for any new particle effect, to setup it’s starting parameters which control how particles are generated when called.  These are also the most tricky to configure to get the effect you want.

    Supplemented Update

As we are aiming for a self sustained effect (a constant fireball) we want to generate new particles to replace those that die during the cause of our fireball shot, so we override update to add more particles each update.  This is also supplemented by an effect specific attribute “CycleMeter” to control how often new particles should happen.  (0 = every frame, 10 = every 10 seconds), the timing is set in the “ParticleCycleTime” attribute of the emitter.

    Supplemented Initialise Particle

As we want the particles to follow the emitter and not fly of in a random direction (which is the default), we fix the particles position to the emitters position.  We could enhance this if we wished to make the particle circle around the emitter if we wished.

The effect that this will give us will be a sustained burst of particles that are constantly generated on top of the emitter.

 


 

Not forgetting our actual particle

With all this code in lace we still need a texture for our particle to draw, so download the code from the beginning of this article and copy the Explosion.PNG image from the content folder, create a new folder in your content project called “Particles” and paste it there.

explosion

Explosion Particle

Now it may not look like much at the moment, but just wait and see what the particle engine makes of it.

 


 

Calling the effect

So now that we have our effect, lets bring the fire, this is simple enough since we have a separate function in the trooper section of StarTroopeSprites for the trooper to fire, so add the following to the TrooperFire function:

In here we:

  1. create new emitter for the effect we just setup
  2. initialised the emitter with the Explosion sprite
  3. Set it’s position, velocity and acceleration
  4. Set the Particle cycle time to 0 so that it constantly spews particles (but if you wanted to make the fireball splutter just increase this slightly)
  5. And finally hand over the emitter to our Particle Manager to control

Run the game now and when you shoot your fireball, it should be followed by a nice new particle enabled fireball.

Fire01 image[6]

Old fireball

New Fireball

 

 


 

But wait there’s more.

A good thing to remember with particle effects is that we don’t just have to live with one effect, we can combine effects in many different ways to get a better result.  If you look back the the previous post you will notice a nice little smoke plume emanating from the tail of our fireball, fire emits smoke doesn’t it Smile

So lets add another effect to our list, add the following to the ParticleEmitters class:

Now this effect is similar to our Fireball effect with a few minor differences:

    It lasts a bit longer (min and max lifetime are greater) as smoke lingers
    It is slower (min and max speed are reduced)
    The acceleration is also slower so that the smoke gets left behind
    We use a different blend effect for better results

If we add this now to our fireball launch code in StarTrooperSprites we get a much nicer effect (I’ve also moved it to a separate function to make it more friendly), so remove the code added above in the “TrooperFire” function for the fireball effect and add the following function:

And just add the following call to the “TrooperFire” function:

 

This gives us our flaming ball of death, beware Condors!!!

Fireball-New


Draw Order

A quick note about draw order.  The current particle implementation above does not have any facilities for managing draw order as part of the effects, that being which effect gets drawn on top of which.

For example reverse the order in which the smoke and explosion effects are drawn and have a look at the corresponding result.  You should see this:

image

Not quite as good is it as it now appears we have fire from smoke?, not my cup of tea.

So take care using this and consider in your experiments (see below) which order you want to draw your effects.  There are a couple of ways to handle this more programmatically, like adding a sort to the Pool class based on an attribute in the emitter, but this wouldn’t give you as much flexibility as you might think.

Choose wisely as to your approach and beware of the unintended consequences of your developments Open-mouthed smile

One problem which can only be really handled by having multiple particle managers, would be to have the ability to differentiate between foreground effects (like what we have) and background effects (like clouds below the player or smoke rising from a scared city below).

 


 

Experimentation

Now the main thing with particle effects is experimentation.  the above effect took me approx 1 hour to put together, here’s a little run down of what it took to get to this point

image image image image image
1st run, way too many particles and they didn’t follow the emitter, except flame up Less particles but they didn’t last long enough or spawn quick enough.  Also too big Got the fireball right but we needed more Great effect, something to keep for later.  Not the ball I wanted.
May be to use in a different colour as a plasma ball?
The end result.

This is why most AAA rated games have dedicated teams (not just individuals) for creating and managing effects like this.  It can take a fair bit of time to get it right and within budget (both Time and game update/draw costs).


Conclusion and a final note.

 
With all this going on it’s easy to forget that fantastic effects come at a cost, more effects means more to draw and heavy on the graphics card.  You might be able to run big shiny and fabulous effects on you development machine with a lofty DX 10/11 graphics card and oodles of memory / cpu.  But remember the audience you are aiming for, XBOX, laptops/networks?, Windows Mobile.
 
you have a few choices add some configuration to up the graphics to the max for high spec machines and lower settings for those of us on a budget or want to game on the go, or aim for a middle ground so you get the same look and feel no matter the device you use.
 
For instance, the main reason I dropped the fiery wall of death, the first thing I ended up with (apart from it not being what I was aiming for), was because as soon as I hade more then 5 of then, my poor laptop slowed right down because it was spewing out millions of particles (pretty obvious really)

This prompted my next intermission on performance, a quick and easy way to monitor it and the cost of the effects I was generating.

Lets bring the numbers!

Technorati Tags: ,
%d bloggers like this: