1、粒子對象類--開發對象Particle類和粒子集合ParticleSet類
- package wyf.wpf;//聲明包語句
- //每個Particle對象代表一個粒子對象
- public class Particle{
- int color;//粒子顏色
- int r;//粒子半徑
- double vertical_v;//垂直速度
- double horizontal_v;//水平速度
- int startX;//開始x座標
- int startY;//開始y座標
- int x;//當前x座標
- int y;//當前y座標
- double startTime;//起始時間
- //構造器,初始化成員變量
- public Particle(int color, int r, double vertical_v,
- double horizontal_v, int x, int y, double startTime){
- this.color = color; //初始化粒子顏色
- this.r = r; //初始化粒子半徑
- this.vertical_v = vertical_v; //初始化豎直方向速度
- this.horizontal_v = horizontal_v; //初始化水平方向上速度
- this.startX = x; //初始化開始位置的X座標
- this.startY = y; //初始化開始位置的Y座標
- this.x = x; //初始化實時X座標
- this.y = y; //初始化實時Y座標
- this.startTime = startTime; //初始化開始運動的時間
- }
- }
ParticleSet類
- package wyf.wpf; //聲明包語句
- import java.util.ArrayList; //引入相關類
- import android.graphics.Color; //引入相關類
- //ParticleSet類負責管理和添加粒子對象
- public class ParticleSet{
- ArrayList<Particle> particleSet; //用於存放Particle對象的集合
- //構造器,初始化粒子集合
- public ParticleSet(){
- particleSet = new ArrayList<Particle>();
- }
- //方法:向粒子集合中添加指定個數的粒子對象
- public void add(int count, double startTime){
- for(int i=0; i<count; i++){ //創建count個數的Particle對象
- int tempColor = this.getColor(i); //獲得粒子顏色
- int tempR = 1; //粒子半徑
- double tempv_v = -30 + 10*(Math.random()); //隨機產生粒子豎直方向上速度
- double tempv_h = 10 - 20*(Math.random()); //隨機產生粒子水平方向上速度
- int tempX = 160; //粒子的X座標是固定的
- int tempY = (int)(100 - 10*(Math.random())); //隨機產生粒子Y座標
- //創建Particle對象
- Particle particle = new Particle(tempColor, tempR, tempv_v, tempv_h, tempX, tempY, startTime);
- particleSet.add(particle);//將創建好的Particle對象添加到列表中
- }
- }
- //方法:獲取指定索引的顏色
- public int getColor(int i){
- int color = Color.RED;
- switch(i%4){ //對i進行分支判斷
- case 0:
- color = Color.RED; //將顏色設爲紅色
- break;
- case 1:
- color = Color.GREEN;//將顏色設爲綠色
- break;
- case 2:
- color = Color.YELLOW;//將顏色設爲黃色
- break;
- case 3:
- color = Color.GRAY;//將顏色設爲灰色
- break;
- }
- return color; //返回得到的顏色
- }
- }
2、開發焰火粒子系統的物理引擎ParticleThread類的代碼
- package wyf.wpf; //聲明包語句
- import java.util.ArrayList; //引入相關類
- //繼承自Thread的類,主要功能是添加粒子並修改粒子的位置
- public class ParticleThread extends Thread{
- boolean flag; //線程執行標誌位
- ParticleView father; //ParticleView對象引用
- int sleepSpan = 80; //線程休眠時間
- double time = 0; //物理引擎的時間軸
- double span = 0.15; //每次計算粒子的位移時採用的時間間隔
- //ParticleThread類的構造器
- public ParticleThread(ParticleView father){
- this.father = father;
- this.flag = true; //設置線程執行標誌位爲true
- }
- //線程的執行方法
- public void run(){
- while(flag){
- father.ps.add(5, time); //每次添加10個粒子
- ArrayList<Particle> tempSet = father.ps.particleSet;//獲取粒子集合
- int count = tempSet.size(); //記錄粒子集合的大小
- for(int i=0; i<count; i++){ //遍歷粒子集合,修改其軌跡
- Particle particle = tempSet.get(i);
- double timeSpan = time - particle.startTime; //計算從程序開始到現在經過的時間間隔
- int tempx = (int)(particle.startX+particle.horizontal_v*timeSpan); //計算出粒子的X座標
- int tempy = (int)(particle.startY + 4.9*timeSpan*timeSpan + particle.vertical_v*timeSpan);
- if(tempy>ParticleView.DIE_OUT_LINE){ //如果超過屏幕下邊沿
- tempSet.remove(particle); //從粒子集合衝移除該Particle對象
- count = tempSet.size(); //重新設置粒子個數
- }
- particle.x = tempx; //修改粒子的X座標
- particle.y = tempy; //修改粒子的Y座標
- }
- time += span; //將時間延長
- try{
- Thread.sleep(sleepSpan); //休眠一段時間
- }
- catch(Exception e){
- e.printStackTrace(); //捕獲並打印異常
- }
- }
- }
- }
3、視圖類--開發視圖類ParticleView及其相關類
- package wyf.wpf; //聲明包語句
- import java.util.ArrayList; //引入相關類
- import android.content.Context; //引入相關類
- import android.graphics.Canvas; //引入相關類
- import android.graphics.Color; //引入相關類
- import android.graphics.Paint; //引入相關類
- import android.graphics.RectF; //引入相關類
- import android.view.SurfaceHolder; //引入相關類
- import android.view.SurfaceView; //引入相關類
- //繼承自SurfaceView並實現SurfaceHolder.Callback接口的類
- public class ParticleView extends SurfaceView implements SurfaceHolder.Callback{
- public static final int DIE_OUT_LINE = 420;//粒子的Y座標超過該值會從粒子集合移除
- DrawThread dt; //後臺刷新屏幕線程
- ParticleSet ps; //ParticleSet對象引用
- ParticleThread pt; //ParticleThread對象引用
- String fps = "FPS:N/A"; //聲明幀速率字符串
- //構造器,初始化主要成員變量
- public ParticleView(Context context) {
- super(context); //調用父類構造器
- this.getHolder().addCallback(this); //添加Callback接口
- dt = new DrawThread(this, getHolder()); //創建DrawThread對象
- ps = new ParticleSet(); //創建ParticleSet對象
- pt = new ParticleThread(this); //創建ParticleThread對象
- }
- //方法:繪製屏幕
- public void doDraw(Canvas canvas){
- canvas.drawColor(Color.BLACK); //清屏
- ArrayList<Particle> particleSet = ps.particleSet; //獲得ParticleSet對象中的粒子集合對象
- Paint paint = new Paint(); //創建畫筆對象
- for(int i=0;i<particleSet.size();i++){ //遍歷粒子集合,繪製每個粒子
- Particle p = particleSet.get(i);
- paint.setColor(p.color); //設置畫筆顏色爲粒子顏色
- int tempX = p.x; //獲得粒子X座標
- int tempY = p.y; //獲得粒子Y座標
- int tempRadius = p.r; //獲得粒子半徑
- RectF oval = new RectF(tempX, tempY, tempX+2*tempRadius, tempY+2*tempRadius);
- canvas.drawOval(oval, paint); //繪製橢圓粒子
- }
- paint.setColor(Color.WHITE); //設置畫筆顏色
- paint.setTextSize(18); //設置文字大小
- paint.setAntiAlias(true); //設置抗鋸齒
- canvas.drawText(fps, 15, 15, paint);//畫出幀速率字符串
- }
- @Override
- public void surfaceChanged(SurfaceHolder holder, int format, int width,
- int height) {//重寫surfaceChanged方法
- }
- @Override
- public void surfaceCreated(SurfaceHolder holder) {//從寫surfaceCreated方法
- if(!dt.isAlive()){ //如果DrawThread沒有啓動,就啓動這個線程
- dt.start();
- }
- if(!pt.isAlive()){ //如果ParticleThread沒有啓動,就啓動這個線程
- pt.start();
- }
- }
- @Override
- public void surfaceDestroyed(SurfaceHolder holder) {//重寫surfaceDestroyed方法
- dt.flag = false; //停止線程的執行
- dt = null; //將dt指向的對象聲明爲垃圾
- }
- }
4、DrawThread類
- package wyf.wpf;//聲明包語句
- import android.graphics.Canvas;//引入相關類
- import android.view.SurfaceHolder;//引入相關類
- //繼承自Thread的子類,負責刷新屏幕
- public class DrawThread extends Thread{
- ParticleView pv; //ParticleView對象引用
- SurfaceHolder surfaceHolder; //SurfaceHolder對象引用
- boolean flag; //線程執行標誌位
- int sleepSpan = 15; //睡眠時間
- long start = System.nanoTime(); //記錄起始時間,該變量用於計算幀速率
- int count=0; //記錄幀數,該變量用於計算幀速率
- //構造器,初始化主要成員變量
- public DrawThread(ParticleView pv,SurfaceHolder surfaceHolder){
- this.pv = pv;
- this.surfaceHolder = surfaceHolder;
- this.flag = true; //設置線程執行標誌位爲true
- }
- //線程執行方法
- public void run(){
- Canvas canvas = null; //聲明一個Canvas對象
- while(flag){
- try{
- canvas = surfaceHolder.lockCanvas(null);//獲取ParticleView的畫布
- synchronized(surfaceHolder){
- pv.doDraw(canvas); //調用ParticleView的doDraw方法進行繪製
- }
- }
- catch(Exception e){
- e.printStackTrace(); //捕獲並打印異常
- }
- finally{
- if(canvas != null){ //如果canvas不爲空
- surfaceHolder.unlockCanvasAndPost(canvas);//surfaceHolder解鎖並將畫布對象傳回
- }
- }
- this.count++;
- if(count == 20){ //如果計滿20幀
- count = 0; //清空計數器
- long tempStamp = System.nanoTime();//獲取當前時間
- long span = tempStamp - start; //獲取時間間隔
- start = tempStamp; //爲start重新賦值
- double fps = Math.round(100000000000.0/span*20)/100.0;//計算幀速率
- pv.fps = "FPS:"+fps;//將計算出的幀速率設置到BallView的相應字符串對象中
- }
- try{
- Thread.sleep(sleepSpan);//線程休眠一段時間
- }
- catch(Exception e){
- e.printStackTrace();//捕獲並打印異常
- }
- }
- }
- }
6、Activity類
- package wyf.wpf; //聲明包語句
- import android.app.Activity; //引入相關類
- import android.os.Bundle; //引入相關類
- import android.view.Window; //引入相關類
- import android.view.WindowManager; //引入相關類
- //繼承自Activity的子類
- public class Sample_7_2 extends Activity {
- @Override
- public void onCreate(Bundle savedInstanceState) { //重寫onCreate方法
- super.onCreate(savedInstanceState);
- requestWindowFeature(Window.FEATURE_NO_TITLE); //設置不顯示標題
- getWindow().setFlags( //設置爲全屏模式
- WindowManager.LayoutParams.FLAG_FULLSCREEN,
- WindowManager.LayoutParams.FLAG_FULLSCREEN);
- ParticleView lz = new ParticleView(this); //創建一個LiZiView對象
- setContentView(lz); //將屏幕設置爲ParticleView對象
- }
- }
還可以將ParticleSet類的add方法稍微修改成瀑布粒子系統