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