[ACCEPTED]-How to create fireworks particle graphics effect on android-effects
I just released the v1.1 of a library that 5 does particle system for normal android 4 views: https://github.com/plattysoft/Leonids
I know the question is quite old, and 3 you probably had implemented it yourself, but 2 in case you are still interested on using 1 a library, check it out.
import java.util.Random;
import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.os.Handler;
import android.os.Message;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
enum AnimateState
{
asReady, asRunning, asPause;
}
class Rocket
{
public boolean sleep = true;
private float energy, length, mx, my, gravity, ox, oy, x, y, t;
private float vx[], vy[];
private int patch, red, green, blue;
private Random random;
public Rocket( int a, int b, int g )
{
mx = a;
my = b;
gravity = g;
}
public void init( int e, int p, int l, long seed )
{
energy = e;
patch = p + 20;
length = l;
random = new Random( seed );
vx = new float[patch];
vy = new float[patch];
red = ( int )( random.nextFloat() * 128 ) + 128;
blue = ( int )( random.nextFloat() * 128 ) + 128;
green = ( int )( random.nextFloat() * 128 ) + 128;
ox = ( random.nextFloat() * mx / 2 ) + mx / 4;
oy = ( random.nextFloat() * my / 2 ) + my / 4;
for( int i = 0; i < patch; ++i )
{
vx[i] = ( ( random.nextFloat() + random.nextFloat() / 2 ) * energy ) - energy / ( random.nextInt( 2 ) + 1 );
vy[i] = ( ( random.nextFloat() + random.nextFloat() / 2 ) * energy * 7 / 8 ) - energy / ( random.nextInt( 5 ) + 4 );
}
}
public void start()
{
t = 0;
sleep = false;
}
public void doDraw( Canvas canvas, Paint paint )
{
if ( ! sleep )
{
if ( t < length )
{
int i, cr, cg, cb;
double s;
cr = ( int )( random.nextDouble() * 64 ) - 32 + red;
cg = ( int )( random.nextDouble() * 64 ) - 32 + green;
cb = ( int )( random.nextDouble() * 64 ) - 32 + blue;
if ( cr >= 0 && cr <= 256 )
red = cr;
if ( cg >= 0 && cg <= 256 )
green = cg;
if ( cb >= 0 && cb <= 256 )
blue = cb;
int _red = red == 256 ? 255 : red;
int _green = green == 256 ? 255 : green;
int _blue = blue == 256 ? 255 : blue;
int color = Color.rgb( _red, _green, _blue );
paint.setColor( color );
for ( i = 0; i < patch; ++i )
{
s = ( double )t / 100;
x = ( int )( vx[i] * s );
y = ( int )( vy[i] * s - gravity * s * s );
canvas.drawCircle( ox + x, oy - y, 2f, paint );
}
paint.setColor( Color.BLACK );
for ( i = 0; i < patch; ++i )
{
if ( t >= length / 2 )
{
for ( int j = 0; j < 2; ++j )
{
s = ( double ) ( ( t - length / 2 ) * 2 + j ) / 100;
x = ( int )( vx[i] * s );
y = ( int )( vy[i] * s - gravity * s * s );
canvas.drawCircle( ox + x, oy - y, 2f, paint );
}
}
}
++t;
}
else
sleep = true;
}
}
}
class Fireworks
{
/**
* Maximum number of rockets.
*/
public int MaxRocketNumber = 9;
/**
* Controls "energy" of firwork explosion. Default value 850.
*/
public int MaxRocketExplosionEnergy = 950;
/**
* Controls the density of the firework burst. Larger numbers give higher density.
* Default value 90.
*/
public int MaxRocketPatchNumber = 90;
/**
* Controls the radius of the firework burst. Larger numbers give larger radius.
* Default value 68.
*/
public int MaxRocketPatchLength = 68;
/**
* Controls gravity of the firework simulation.
* Default value 400.
*/
public int Gravity = 400;
transient private Rocket rocket[];
transient private boolean rocketsCreated = false;
private int width;
private int height;
Fireworks( int width, int height )
{
this.width = width;
this.height = height;
}
void createRockets()
{
rocketsCreated = true;
Rocket tempRocket[] = new Rocket[MaxRocketNumber];
for ( int i = 0; i < MaxRocketNumber; i++ )
tempRocket[i] = new Rocket( width, height, Gravity );
rocket = tempRocket;
}
public synchronized void reshape( int width, int height )
{
this.width = width;
this.height = height;
rocketsCreated = false;
}
public void doDraw( Canvas canvas, Paint paint )
{
canvas.drawColor( Color.BLACK );
int i, e, p, l;
long s;
boolean sleep;
if ( ! rocketsCreated )
{
createRockets();
}
if ( rocketsCreated )
{
sleep = true;
for ( i = 0; i < MaxRocketNumber; i++ )
sleep = sleep && rocket[i].sleep;
for ( i = 0; i < MaxRocketNumber; ++i )
{
e = ( int )( Math.random() * MaxRocketExplosionEnergy * 3 / 4 ) + MaxRocketExplosionEnergy / 4 + 1;
p = ( int )( Math.random() * MaxRocketPatchNumber * 3 / 4 ) + MaxRocketPatchNumber / 4 + 1;
l = ( int )( Math.random() * MaxRocketPatchLength * 3 / 4 ) + MaxRocketPatchLength / 4 + 1;
s = ( long )( Math.random() * 10000 );
Rocket r = rocket[i];
if ( r.sleep && Math.random() * MaxRocketNumber * l < 2 )
{
r.init( e, p, l, s );
r.start();
}
if ( rocketsCreated )
r.doDraw( canvas, paint );
}
}
}
}
public class FireworkLayout extends SurfaceView implements SurfaceHolder.Callback
{
class GameThread extends Thread
{
private boolean mRun = false;
private SurfaceHolder surfaceHolder;
private AnimateState state;
private Context context;
private Handler handler;
private Paint paint;
Fireworks fireworks;
GameThread( SurfaceHolder surfaceHolder, Context context, Handler handler )
{
this.surfaceHolder = surfaceHolder;
this.context = context;
this.handler = handler;
fireworks = new Fireworks( getWidth(), getHeight() );
paint = new Paint();
paint.setStrokeWidth( 2 / getResources().getDisplayMetrics().density );
paint.setColor( Color.BLACK );
paint.setAntiAlias( true );
}
public void doStart()
{
synchronized ( surfaceHolder )
{
setState( AnimateState.asRunning );
}
}
public void pause()
{
synchronized ( surfaceHolder )
{
if ( state == AnimateState.asRunning )
setState( AnimateState.asPause );
}
}
public void unpause()
{
setState( AnimateState.asRunning );
}
@Override
public void run()
{
while ( mRun )
{
Canvas c = null;
try
{
c = surfaceHolder.lockCanvas( null );
synchronized ( surfaceHolder )
{
if ( state == AnimateState.asRunning )
doDraw( c );
}
}
finally
{
if ( c != null )
{
surfaceHolder.unlockCanvasAndPost( c );
}
}
}
}
public void setRunning( boolean b )
{
mRun = b;
}
public void setState( AnimateState state )
{
synchronized ( surfaceHolder )
{
this.state = state;
}
}
public void doDraw( Canvas canvas )
{
fireworks.doDraw( canvas, paint );
}
public void setSurfaceSize( int width, int height )
{
synchronized ( surfaceHolder )
{
fireworks.reshape( width, height );
}
}
}
private GameThread thread;
@SuppressLint( "HandlerLeak" )
public FireworkLayout( Context context )
{
super( context );
SurfaceHolder holder = getHolder();
holder.addCallback( this );
getHolder().addCallback( this );
thread = new GameThread( holder, context, new Handler() {
@Override
public void handleMessage( Message m ) {
}} );
setFocusable( true );
}
@Override
public void surfaceChanged( SurfaceHolder holder, int format, int width, int height )
{
thread.setSurfaceSize( width, height );
}
@Override
public void surfaceCreated( SurfaceHolder holder )
{
thread.setRunning( true );
thread.doStart();
thread.start();
}
@Override
public void surfaceDestroyed( SurfaceHolder holder )
{
boolean retry = true;
thread.setRunning( false );
while ( retry )
{
try
{
thread.join();
retry = false;
}
catch ( InterruptedException e )
{
}
}
}
}
use:
firework = new FireworkView( this );
LinearLayout surface = (LinearLayout) findViewById( R.id.surface );
surface.addView( firework );
0
That's a very abstract (and interesting) question 9 but far too complex to answer in details.
What 8 you're really looking for is probably a 7 sort of a modified particle system. A particle 6 system is basically an engine for particles 5 that includes a physics engine.
However, what 4 you should focus on are these:
- Memory Pool pattern - useful for fireworks since you don't want to allocate objects during runtime.
- Particle system tutorial - great and the tutorial is specifically for Android.
- Particle system - great, but for C++.
Once you built 3 it (or gotten an understanding about it) you 2 can easily convert it to the Canvas
system, although 1 OpenGL
is the preferable alternative.
More Related questions
We use cookies to improve the performance of the site. By staying on our site, you agree to the terms of use of cookies.