如何在android上创建烟花粒子图形效果
Posted
技术标签:
【中文标题】如何在android上创建烟花粒子图形效果【英文标题】:How to create fireworks particle graphics effect on android 【发布时间】:2011-07-21 11:04:08 【问题描述】:有人知道如何在画布上绘制烟花效果吗? 电线动态壁纸(免费应用程序)中有一个很好的例子。
在那里,许多点像爆炸一样移动并留下痕迹,然后逐渐消失。我认为每个移动点都有某种运动模糊,我不确定如何创建。
欢迎任何想法或相关示例的链接。
【问题讨论】:
【参考方案1】:我刚刚发布了一个库的 v1.1,它为普通的 android 视图执行粒子系统:https://github.com/plattysoft/Leonids
我知道这个问题已经很老了,您可能已经自己实现了它,但如果您仍然对使用库感兴趣,请检查一下。
【讨论】:
感谢您的辛勤工作,只是一个简短的问题 - 我希望粒子在随机位置弹出,然后在 2 秒内淡出。我一直在寻找如何使用您的库来实现随机粒子放置。 理论上,你可以有一个和屏幕一样大的视图,并确保重力没有设置为 CENTER,应该这样做。 我试过你的方法。但它一次生成一颗星。我真正想要的是。假设 20/30 小粒子(星)在随机位置以随机大小生成,然后在随机时间开始淡出,随着每一个淡出,另一颗星在随机位置淡入。 你可以使用 2 个粒子系统来完成。一个有 20 个,一个有 10 个。我尝试了 Gravity.NO_GRAVITY 并按预期工作。但是,我们应该将此讨论移至 github 中的一张票。【参考方案2】: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 )
使用:
firework = new FireworkView( this );
LinearLayout surface = (LinearLayout) findViewById( R.id.surface );
surface.addView( firework );
【讨论】:
谢谢,我想下一步是让它留下痕迹,不要这么快消失。 有人可以帮忙编辑这个答案,为调用者/使用提供示例代码吗?我什至不知道哪种方法是起点。【参考方案3】:这是一个非常抽象(且有趣)的问题,但过于复杂,无法详细回答。
您真正要寻找的可能是一种经过修改的粒子系统。粒子系统基本上是包含物理引擎的粒子引擎。
但是,你应该关注的是这些:
Memory Pool pattern - 对烟花很有用,因为您不想在运行时分配对象。 Particle system tutorial - 很棒,而且该教程专门针对 Android。 Particle system - 很棒,但适用于 C++。一旦您构建了它(或了解了它),您就可以轻松地将其转换为Canvas
系统,尽管OpenGL
是更好的选择。
【讨论】:
感谢 Victor 提供了一个有用的答案(而不是另一个)。我正在尝试在 SurfaceView 上创建它。如果您查看此动态壁纸market.android.com/details?id=com.aoi.livewallpaper.Fireworks,您会发现一个点会使尾巴变得模糊。我所需要的只是做一个像彗星一样的运动,然后剩下的就是数学。我认为油漆过滤器会有所帮助。 Particle system tutorial,从 Internet Wayback Machine 备份。以上是关于如何在android上创建烟花粒子图形效果的主要内容,如果未能解决你的问题,请参考以下文章
Unity3D_(Shuriken粒子系统)制作简单的烟花爆炸效果
iOS 烟花撒花效果,图层渐变,图层倒影特效。CAEmitterLayer粒子发射器
6 cocos2dx粒子效果,类图关系,系统原生粒子和自己定义粒子效果,粒子编译器软件,爆炸粒子效果,烟花效果,火焰效果,流星效果,漩涡粒子效果,雪花效果,烟雾效果,太阳效果,下雨效果