焰火粒子系统

1、粒子对象类--开发对象Particle类和粒子集合ParticleSet类

 

  1. package wyf.wpf;//声明包语句  
  2. //每个Particle对象代表一个粒子对象  
  3. public class Particle{  
  4.     int color;//粒子颜色  
  5.     int r;//粒子半径  
  6.     double vertical_v;//垂直速度  
  7.     double horizontal_v;//水平速度  
  8.     int startX;//开始x座标  
  9.     int startY;//开始y座标  
  10.     int x;//当前x座标  
  11.     int y;//当前y座标  
  12.     double startTime;//起始时间  
  13.     //构造器,初始化成员变量  
  14.     public Particle(int color, int r, double vertical_v,   
  15.             double horizontal_v, int x, int y, double startTime){  
  16.         this.color = color; //初始化粒子颜色  
  17.         this.r = r; //初始化粒子半径  
  18.         this.vertical_v = vertical_v;   //初始化竖直方向速度  
  19.         this.horizontal_v = horizontal_v;   //初始化水平方向上速度  
  20.         this.startX = x;        //初始化开始位置的X座标  
  21.         this.startY = y;        //初始化开始位置的Y座标  
  22.         this.x = x;                     //初始化实时X座标  
  23.         this.y = y;                         //初始化实时Y座标  
  24.         this.startTime = startTime;         //初始化开始运动的时间  
  25.     }  

ParticleSet类

 

  1. package wyf.wpf;        //声明包语句  
  2. import java.util.ArrayList;     //引入相关类  
  3. import android.graphics.Color;  //引入相关类  
  4. //ParticleSet类负责管理和添加粒子对象  
  5. public class ParticleSet{  
  6.     ArrayList<Particle> particleSet;        //用于存放Particle对象的集合  
  7.     //构造器,初始化粒子集合  
  8.     public ParticleSet(){  
  9.         particleSet = new ArrayList<Particle>();  
  10.     }  
  11.     //方法:向粒子集合中添加指定个数的粒子对象  
  12.     public void add(int count, double startTime){  
  13.         for(int i=0; i<count; i++){     //创建count个数的Particle对象  
  14.             int tempColor = this.getColor(i);   //获得粒子颜色  
  15.             int tempR = 1;      //粒子半径  
  16.             double tempv_v = -30 + 10*(Math.random());  //随机产生粒子竖直方向上速度  
  17.             double tempv_h = 10 - 20*(Math.random());   //随机产生粒子水平方向上速度  
  18.             int tempX = 160;    //粒子的X座标是固定的  
  19.             int tempY = (int)(100 - 10*(Math.random()));    //随机产生粒子Y座标  
  20.             //创建Particle对象  
  21.             Particle particle = new Particle(tempColor, tempR, tempv_v, tempv_h, tempX, tempY, startTime);  
  22.             particleSet.add(particle);//将创建好的Particle对象添加到列表中  
  23.         }  
  24.     }  
  25.     //方法:获取指定索引的颜色  
  26.     public int getColor(int i){  
  27.         int color = Color.RED;  
  28.         switch(i%4){    //对i进行分支判断  
  29.         case 0:  
  30.             color = Color.RED;  //将颜色设为红色  
  31.             break;  
  32.         case 1:  
  33.             color = Color.GREEN;//将颜色设为绿色  
  34.             break;  
  35.         case 2:  
  36.             color = Color.YELLOW;//将颜色设为黄色  
  37.             break;  
  38.         case 3:  
  39.             color = Color.GRAY;//将颜色设为灰色  
  40.             break;  
  41.         }  
  42.         return color;       //返回得到的颜色  
  43.     }  

2、开发焰火粒子系统的物理引擎ParticleThread类的代码

 

  1. package wyf.wpf;        //声明包语句  
  2. import java.util.ArrayList; //引入相关类  
  3. //继承自Thread的类,主要功能是添加粒子并修改粒子的位置  
  4. public class ParticleThread extends Thread{  
  5.     boolean flag;       //线程执行标志位  
  6.     ParticleView father;        //ParticleView对象引用  
  7.     int sleepSpan = 80;     //线程休眠时间  
  8.     double time = 0;        //物理引擎的时间轴  
  9.     double span = 0.15;     //每次计算粒子的位移时采用的时间间隔  
  10.     //ParticleThread类的构造器  
  11.     public ParticleThread(ParticleView father){  
  12.         this.father = father;  
  13.         this.flag = true;       //设置线程执行标志位为true  
  14.     }  
  15.     //线程的执行方法  
  16.     public void run(){  
  17.         while(flag){  
  18.             father.ps.add(5, time); //每次添加10个粒子  
  19.             ArrayList<Particle> tempSet = father.ps.particleSet;//获取粒子集合  
  20.             int count = tempSet.size();     //记录粒子集合的大小  
  21.               
  22.             for(int i=0; i<count; i++){     //遍历粒子集合,修改其轨迹  
  23.                 Particle particle = tempSet.get(i);  
  24.                 double timeSpan = time - particle.startTime;    //计算从程序开始到现在经过的时间间隔  
  25.                 int tempx = (int)(particle.startX+particle.horizontal_v*timeSpan);  //计算出粒子的X座标  
  26.                 int tempy = (int)(particle.startY + 4.9*timeSpan*timeSpan + particle.vertical_v*timeSpan);  
  27.                 if(tempy>ParticleView.DIE_OUT_LINE){                        //如果超过屏幕下边沿  
  28.                     tempSet.remove(particle);       //从粒子集合冲移除该Particle对象  
  29.                     count = tempSet.size();         //重新设置粒子个数  
  30.                 }  
  31.                 particle.x = tempx;                 //修改粒子的X座标  
  32.                 particle.y = tempy;                 //修改粒子的Y座标  
  33.             }  
  34.             time += span;                               //将时间延长  
  35.             try{  
  36.                 Thread.sleep(sleepSpan);                    //休眠一段时间  
  37.             }  
  38.             catch(Exception e){  
  39.                 e.printStackTrace();                //捕获并打印异常  
  40.             }  
  41.         }  
  42.     }  

3、视图类--开发视图类ParticleView及其相关类

 

  1. package wyf.wpf;            //声明包语句  
  2. import java.util.ArrayList;     //引入相关类  
  3. import android.content.Context;     //引入相关类  
  4. import android.graphics.Canvas; //引入相关类  
  5. import android.graphics.Color;  //引入相关类  
  6. import android.graphics.Paint;  //引入相关类  
  7. import android.graphics.RectF;  //引入相关类  
  8. import android.view.SurfaceHolder;  //引入相关类  
  9. import android.view.SurfaceView;    //引入相关类  
  10. //继承自SurfaceView并实现SurfaceHolder.Callback接口的类  
  11. public class ParticleView extends SurfaceView implements SurfaceHolder.Callback{  
  12.     public static final int DIE_OUT_LINE = 420;//粒子的Y座标超过该值会从粒子集合移除  
  13.     DrawThread dt;      //后台刷新屏幕线程  
  14.     ParticleSet ps;     //ParticleSet对象引用  
  15.     ParticleThread pt;  //ParticleThread对象引用  
  16.     String fps = "FPS:N/A";     //声明帧速率字符串  
  17.     //构造器,初始化主要成员变量  
  18.     public ParticleView(Context context) {  
  19.         super(context); //调用父类构造器  
  20.         this.getHolder().addCallback(this); //添加Callback接口  
  21.         dt = new DrawThread(this, getHolder()); //创建DrawThread对象  
  22.         ps = new ParticleSet();                 //创建ParticleSet对象  
  23.         pt = new ParticleThread(this);          //创建ParticleThread对象  
  24.     }     
  25.     //方法:绘制屏幕  
  26.     public void doDraw(Canvas canvas){  
  27.         canvas.drawColor(Color.BLACK);      //清屏  
  28.         ArrayList<Particle> particleSet = ps.particleSet;   //获得ParticleSet对象中的粒子集合对象  
  29.         Paint paint = new Paint();  //创建画笔对象  
  30.         for(int i=0;i<particleSet.size();i++){      //遍历粒子集合,绘制每个粒子  
  31.             Particle p = particleSet.get(i);  
  32.             paint.setColor(p.color);        //设置画笔颜色为粒子颜色  
  33.             int tempX = p.x;        //获得粒子X座标  
  34.             int tempY = p.y;        //获得粒子Y座标  
  35.             int tempRadius = p.r;   //获得粒子半径  
  36.             RectF oval = new RectF(tempX, tempY, tempX+2*tempRadius, tempY+2*tempRadius);  
  37.             canvas.drawOval(oval, paint);       //绘制椭圆粒子  
  38.         }  
  39.         paint.setColor(Color.WHITE);    //设置画笔颜色  
  40.         paint.setTextSize(18);          //设置文字大小  
  41.         paint.setAntiAlias(true);       //设置抗锯齿  
  42.         canvas.drawText(fps, 1515, paint);//画出帧速率字符串  
  43.     }  
  44.     @Override 
  45.     public void surfaceChanged(SurfaceHolder holder, int format, int width,  
  46.             int height) {//重写surfaceChanged方法     
  47.     }  
  48.     @Override 
  49.     public void surfaceCreated(SurfaceHolder holder) {//从写surfaceCreated方法  
  50.         if(!dt.isAlive()){  //如果DrawThread没有启动,就启动这个线程  
  51.             dt.start();  
  52.         }  
  53.         if(!pt.isAlive()){  //如果ParticleThread没有启动,就启动这个线程  
  54.             pt.start();  
  55.         }  
  56.     }  
  57.     @Override 
  58.     public void surfaceDestroyed(SurfaceHolder holder) {//重写surfaceDestroyed方法  
  59.         dt.flag = false;    //停止线程的执行  
  60.         dt = null;          //将dt指向的对象声明为垃圾  
  61.     }     

4、DrawThread类

 

  1. package wyf.wpf;//声明包语句  
  2. import android.graphics.Canvas;//引入相关类  
  3. import android.view.SurfaceHolder;//引入相关类  
  4. //继承自Thread的子类,负责刷新屏幕  
  5. public class DrawThread extends Thread{  
  6.     ParticleView pv;        //ParticleView对象引用  
  7.     SurfaceHolder surfaceHolder;    //SurfaceHolder对象引用  
  8.     boolean flag;           //线程执行标志位  
  9.     int sleepSpan = 15;         //睡眠时间  
  10.     long start = System.nanoTime(); //记录起始时间,该变量用于计算帧速率  
  11.     int count=0;        //记录帧数,该变量用于计算帧速率  
  12.     //构造器,初始化主要成员变量  
  13.     public DrawThread(ParticleView pv,SurfaceHolder surfaceHolder){  
  14.         this.pv = pv;  
  15.         this.surfaceHolder = surfaceHolder;  
  16.         this.flag = true;   //设置线程执行标志位为true  
  17.     }  
  18.     //线程执行方法  
  19.     public void run(){  
  20.         Canvas canvas = null;       //声明一个Canvas对象  
  21.         while(flag){  
  22.             try{  
  23.                 canvas = surfaceHolder.lockCanvas(null);//获取ParticleView的画布  
  24.                 synchronized(surfaceHolder){  
  25.                     pv.doDraw(canvas);          //调用ParticleView的doDraw方法进行绘制  
  26.                 }  
  27.             }  
  28.             catch(Exception e){  
  29.                 e.printStackTrace();            //捕获并打印异常  
  30.             }  
  31.             finally{  
  32.                 if(canvas != null){     //如果canvas不为空  
  33.                     surfaceHolder.unlockCanvasAndPost(canvas);//surfaceHolder解锁并将画布对象传回  
  34.                 }  
  35.             }  
  36.             this.count++;  
  37.             if(count == 20){    //如果计满20帧  
  38.                 count = 0;      //清空计数器  
  39.                 long tempStamp = System.nanoTime();//获取当前时间  
  40.                 long span = tempStamp - start;      //获取时间间隔  
  41.                 start = tempStamp;                  //为start重新赋值  
  42.                 double fps = Math.round(100000000000.0/span*20)/100.0;//计算帧速率  
  43.                 pv.fps = "FPS:"+fps;//将计算出的帧速率设置到BallView的相应字符串对象中  
  44.             }  
  45.             try{  
  46.                 Thread.sleep(sleepSpan);//线程休眠一段时间  
  47.             }  
  48.             catch(Exception e){  
  49.                 e.printStackTrace();//捕获并打印异常  
  50.             }  
  51.         }  
  52.     }  

6、Activity类

 

  1. package wyf.wpf;        //声明包语句  
  2. import android.app.Activity;        //引入相关类  
  3. import android.os.Bundle;           //引入相关类  
  4. import android.view.Window;         //引入相关类  
  5. import android.view.WindowManager;  //引入相关类  
  6. //继承自Activity的子类  
  7. public class Sample_7_2 extends Activity {  
  8.     @Override 
  9.     public void onCreate(Bundle savedInstanceState) {       //重写onCreate方法  
  10.         super.onCreate(savedInstanceState);  
  11.         requestWindowFeature(Window.FEATURE_NO_TITLE);      //设置不显示标题  
  12.         getWindow().setFlags(                                   //设置为全屏模式  
  13.                 WindowManager.LayoutParams.FLAG_FULLSCREEN,   
  14.                 WindowManager.LayoutParams.FLAG_FULLSCREEN);  
  15.         ParticleView lz = new ParticleView(this);       //创建一个LiZiView对象  
  16.         setContentView(lz);                             //将屏幕设置为ParticleView对象  
  17.     }  

还可以将ParticleSet类的add方法稍微修改成瀑布粒子系统

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章