Greetings!

The main purpose of this website is to support Android indie game developers with tutorials, reviews and promotion of their games. The main difficulty for the developers is not to make the game, but to get exposure. To get it out there. If you find anything useful here, please spread the word. Like my page on Facebook, follow me on Google+ or Twitter. Thank you!

Google+ Facebook Twitter

× close

Friday, 6 September 2013

Tutorial - How to create falling snow in AndEngine

The obvious way how to create snow fall is to use Particle System. With the correct parameters, it will create an illusion of real snow falling. Adding wind in one direction is also not a problem. But for my game, I needed a cartoonish looking snow falling in nice swinging motion. This is how I did it.

Start with a simple particle system. You will need a sprite representing a single snow flake. The screen is 800x480 pixels.

  
final BatchedPseudoSpriteParticleSystem particleSystem = new BatchedPseudoSpriteParticleSystem(
    new RectangleParticleEmitter(CAMERA_WIDTH / 2, CAMERA_HEIGHT, CAMERA_WIDTH, 1),
    2, 5, 100, mSnowParticleRegion, 
    this.getVertexBufferObjectManager()
  );
particleSystem.setBlendFunction(GLES20.GL_SRC_ALPHA, GLES20.GL_ONE);
particleSystem.addParticleInitializer(new VelocityParticleInitializer<Entity>(-3, 3, -20, -40));
particleSystem.addParticleInitializer(new AccelerationParticleInitializer<Entity>(-3, 3, -3, -5));
particleSystem.addParticleInitializer(new RotationParticleInitializer<Entity>(0.0f, 360.0f));
particleSystem.addParticleInitializer(new ExpireParticleInitializer<Entity>(10f));
particleSystem.addParticleInitializer(new ScaleParticleInitializer<Entity>(0.2f, 0.5f));


particleSystem.addParticleModifier(new AlphaParticleModifier<Entity>(6f, 10f, 1.0f, 0.0f));

scene.attachChild(particleSystem);

  • VelocityParticleInitializer - tells the particle system to shoot particles softly to left and right (-3 and 3 is "speed") and a bit faster down
  • AccelerationParticleInitializer - similar to velocity, giving them acceleration (they will accelerate a little over time)
  • RotationParticleInitializer - rotate each snow flake randomly (my particle is almost a circle, so it doesn't make much sense)
  • ExpireParticleInitializer - it will take 10 seconds for the particle to expire (dissapear), this is about the time the fastest reaches the bottom of the screen
  • ScaleParticleInitializer - particles will be scaled from 20% to 50% of the original sprite
  • AlphaParticleModifier - the only modifier here, after 6 seconds, start fading out the snow flake
If you use this, you will get quite a nice snowfall, but all the particles will move almost on a straight line. You can simply write some random particle modifier that will push the particle left or right to give it a bit of realism.  But if you want to add a swinging motion, you are in trouble. Notice that we are creating only one Modifier object for all particles. Modifiers do not have state - they are staless. They can work with the current particle and the particle has a state. It hold a reference to the Entity, i.e. the Sprite. So you have access to all it's properties.

It's quite easy to create swinging motion, but not without a state. We need at least the starting X coordinate. So how do you make a swinging motion? You add a new modifier to EACH particle. This is how:

First create a particle initializer, that will add a modifier to each particle.


  
public class YourEntityModifierParticleInitializer<T extends IEntity> implements
    IParticleInitializer<T> {
  
  @Override
  public void onInitializeParticle(Particle<T> pParticle) {

      pParticle.getEntity().registerEntityModifier(
           new YourEntityModifier());

  }
}



And then add this to initializers:

  
particleSystem.addParticleInitializer(new YourEntityModifierParticleInitializer());


Then you can pass any information to the initializer. Or simply get the information from the entity in the initializer. Now how would a swinging motion entity modifier look like? This is my modifier that uses a growing sine wave to create a swinging motion. Only the important part is shown:

  

public class PositionXSwingModifier extends SingleValueSpanEntityModifier {
...
  public PositionXSwingModifier(float pDuration, float pFromValue, float pToValue,
        float pFromMagnitude, float pToMagnitude) {
    // fromValue is usually 0
    // toValue means how many times will the sine wave oscillate
    // every 2pi is full sin wave
    super(pDuration, pFromValue, pToValue);
    mFromMagnitude = pFromMagnitude;
    mToMagnitude = pToMagnitude;
  }
...

  @Override
  protected void onSetValue(IEntity pItem, float pPercentageDone, float pValue) {
    // current magnitude based on percentage
    float currentMagnitude = mFromMagnitude + (mToMagnitude - mFromMagnitude) * pPercentageDone;
    // current sine wave value
    float currentSinValue = (float) Math.sin(pValue);
    // change the x position of the flake
    pItem.setX(mInitialX + currentMagnitude * currentSinValue);
  }

...
}




I have created my own initializer that adds this modifier to each particle with some randomization of the parameters. And this is how I initialize it:

 
particleSystem.addParticleInitializer(
  new RegisterXSwingEntityModifierInitializer(
    10f, 0f, (float) Math.PI * 8, 3f, 25f, true));

Here's the full eclipse project with source code (includes the particle texture) and the apk for download:

Download Project
Download APK
Martin Varga is a Czech software developer who likes pygmy owls (hence Kulíš), running, ramen, travelling and living in foreign countries. He is also known as smartus or sm4 on the internet (read as smartass, but there are too many of them). He currently tries to make games in AndEngine like Mr. Dandelion's Adventures and hangs around a lot at the AndEngine forums.