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
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