焰火粒子系統

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方法稍微修改成瀑布粒子系統

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