Android应用开发之Android小程序--模拟焰火粒子和瀑布粒子
白羽 2018-08-10 来源 :网络 阅读 782 评论 0

摘要:本文将带你了解Android应用开发之Android小程序--模拟焰火粒子和瀑布粒子,希望本文对大家学Android有所帮助

        本文将带你了解Android应用开发之Android小程序--模拟焰火粒子和瀑布粒子,希望本文对大家学Android有所帮助


   需要注意的是,粒子系统和前面开发的物理小球之间有类似的地方,其都是通过数学方法和物理公式模拟客观世界中物体的运动轨迹。不同的是物理小球更强调个体运动,而焰火粒子系统更注重整体感觉,这点区别在代码中也能体现。
   1、开发粒子对象Particle类:
Java代码  package xiao.fuyan.particle;    /**  * Created by xiao on 2017/2/10.  */  public class Particle {      //粒子半径      int r;      //粒子颜色      int color;      //垂直速度      double v_v;      //水平速度      double h_v;      //初始坐标      int startX;      int startY;      //实时坐标      int x, y;      //起始时间      double startTime;        //构造器      public Particle(int color, int r, double v_v, double h_v, int x, int y, double startTime){          //初始化各个变量          this.color = color;          this.r = r;          this.v_v = v_v;          this.h_v = h_v;          this.startX = x;          this.startY = y;          this.x = x;          this.y = y;          this.startTime = startTime;      }  }  package xiao.fuyan.particle;

/**
 * Created by xiao on 2017/2/10.
 */
public class Particle {
    //粒子半径
    int r;
    //粒子颜色
    int color;
    //垂直速度
    double v_v;
    //水平速度
    double h_v;
    //初始坐标
    int startX;
    int startY;
    //实时坐标
    int x, y;
    //起始时间
    double startTime;

    //构造器
    public Particle(int color, int r, double v_v, double h_v, int x, int y, double startTime){
        //初始化各个变量
        this.color = color;
        this.r = r;
        this.v_v = v_v;
        this.h_v = h_v;
        this.startX = x;
        this.startY = y;
        this.x = x;
        this.y = y;
        this.startTime = startTime;
    }
}   2、开发粒子集合ParticleSet类:
Java代码  package xiao.fuyan.particle;    import android.graphics.Color;    import java.util.ArrayList;    /**  * Created by xiao on 2017/2/10.  */  public class ParticleSet {      //用于存放Particle对象的集合      ArrayList<Particle> particleSet;      //构造器,      public ParticleSet(){          particleSet = new ArrayList<Particle>();      }        //向粒子集合中添加指定个数的粒子对象      public void add(int count, double startTime){          for(int i =0; i < count; i++){                            //该段代码是开发焰火粒子              //获取粒子对象的颜色              int tempColor = this.getColor(i);              //设置粒子半径              int tempR = 3;              //随机产生粒子竖直方向上的速度              double tempv_v = -30 + 10 * (Math.random());              //同上获取水平方向上的速度              double temph_v = 10 - 20 * (Math.random());                //粒子的X坐标是固定的              int tempX = 160;              //随机产生Y坐标,90 - 100之间              int tempY = (int) (100 - 10 * (Math.random()));                Particle particle = new Particle(tempColor, tempR, tempv_v, temph_v, tempX, tempY, startTime);              //将创建好的Particle对象添加到列表中              particleSet.add(particle);                //下面代码是将焰火粒子变为瀑布粒子  //            int tempColor = this.getColor(i);  //            //粒子半径  //            int tempR = 3;  //            //竖直方向速度为零  //            double tempv_v = 0;  //            double temph_v = 20 + 10 * (Math.random());  //  //            int tempX = 50;  //            int tempY = (int) (50 - 10 * (Math.random()));  //  //            //创建Particle对象  //            Particle particle = new Particle(tempColor, tempR, tempv_v, temph_v, tempX, tempY, startTime);  //            //将创建好的Particle对象加入列表  //            particleSet.add(particle);          }      }        //获取指定索引的颜色      public int getColor(int i){          int color = Color.RED;          switch (i % 8){              case 0:                  color = Color.RED;                  break;              case 1:                  color = Color.BLUE;                  break;              case 2:                  color = Color.GRAY;                  break;              case 3:                  color = Color.GREEN;                  break;              case 4:                  color = Color.CYAN;                  break;              case 5:                  color = Color.YELLOW;                  break;              case 6:                  color = Color.MAGENTA;                  break;              case 7:                  color = Color.LTGRAY;                  break;          }          return color;      }  }  package xiao.fuyan.particle;

import android.graphics.Color;

import java.util.ArrayList;

/**
 * Created by xiao on 2017/2/10.
 */
public class ParticleSet {
    //用于存放Particle对象的集合
    ArrayList<Particle> particleSet;
    //构造器,
    public ParticleSet(){
        particleSet = new ArrayList<Particle>();
    }

    //向粒子集合中添加指定个数的粒子对象
    public void add(int count, double startTime){
        for(int i =0; i < count; i++){
            
            //该段代码是开发焰火粒子
            //获取粒子对象的颜色
            int tempColor = this.getColor(i);
            //设置粒子半径
            int tempR = 3;
            //随机产生粒子竖直方向上的速度
            double tempv_v = -30 + 10 * (Math.random());
            //同上获取水平方向上的速度
            double temph_v = 10 - 20 * (Math.random());

            //粒子的X坐标是固定的
            int tempX = 160;
            //随机产生Y坐标,90 - 100之间
            int tempY = (int) (100 - 10 * (Math.random()));

            Particle particle = new Particle(tempColor, tempR, tempv_v, temph_v, tempX, tempY, startTime);
            //将创建好的Particle对象添加到列表中
            particleSet.add(particle);

            //下面代码是将焰火粒子变为瀑布粒子
//            int tempColor = this.getColor(i);
//            //粒子半径
//            int tempR = 3;
//            //竖直方向速度为零
//            double tempv_v = 0;
//            double temph_v = 20 + 10 * (Math.random());
//
//            int tempX = 50;
//            int tempY = (int) (50 - 10 * (Math.random()));
//
//            //创建Particle对象
//            Particle particle = new Particle(tempColor, tempR, tempv_v, temph_v, tempX, tempY, startTime);
//            //将创建好的Particle对象加入列表
//            particleSet.add(particle);
        }
    }

    //获取指定索引的颜色
    public int getColor(int i){
        int color = Color.RED;
        switch (i % 8){
            case 0:
                color = Color.RED;
                break;
            case 1:
                color = Color.BLUE;
                break;
            case 2:
                color = Color.GRAY;
                break;
            case 3:
                color = Color.GREEN;
                break;
            case 4:
                color = Color.CYAN;
                break;
            case 5:
                color = Color.YELLOW;
                break;
            case 6:
                color = Color.MAGENTA;
                break;
            case 7:
                color = Color.LTGRAY;
                break;
        }
        return color;
    }
}   3、开发物理引擎ParticleThread类:
Java代码  package xiao.fuyan.particle;    import java.util.ArrayList;    /**  * Created by xiao on 2017/2/10.  */  public class ParticleThread extends Thread {        //线程执行标志位      boolean flag;      //ParticleView对象的引用      ParticleView father;      //线程休眠的时间      int sleepSpan = 80;      //物理引擎的时间轴      double time = 0;      //每次计算粒子的位移时采用的时间间隔      double span = 0.15;        //构造器      public ParticleThread(ParticleView father){          this.father = father;          this.flag = true;      }        //线程执行的方法      @Override      public void run() {          while(flag){              //每次添加五个粒子              father.ps.add(15, time);              //获取粒子集合              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;                  //计算出粒子的X坐标                  int tempX = (int) (particle.startX + particle.h_v * timeSpan);                  //计算Y坐标                  int tempY = (int) (particle.startY + 4.9 * timeSpan * timeSpan + particle.v_v * timeSpan);                    //如果粒子超出屏幕下边沿                  if(tempY > 1920){                      tempSet.remove(particle);                      //重新设置粒子的个数                      count = tempSet.size();                  }                    //修改粒子的坐标                  particle.x = tempX;                  particle.y = tempY;              }                //将时间延长              time += span;              try{                  Thread.sleep(sleepSpan);//休眠一段时间              }catch (Exception e){                  e.printStackTrace();              }          }      }  }  package xiao.fuyan.particle;

import java.util.ArrayList;

/**
 * Created by xiao on 2017/2/10.
 */
public class ParticleThread extends Thread {

    //线程执行标志位
    boolean flag;
    //ParticleView对象的引用
    ParticleView father;
    //线程休眠的时间
    int sleepSpan = 80;
    //物理引擎的时间轴
    double time = 0;
    //每次计算粒子的位移时采用的时间间隔
    double span = 0.15;

    //构造器
    public ParticleThread(ParticleView father){
        this.father = father;
        this.flag = true;
    }

    //线程执行的方法
    @Override
    public void run() {
        while(flag){
            //每次添加五个粒子
            father.ps.add(15, time);
            //获取粒子集合
            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;
                //计算出粒子的X坐标
                int tempX = (int) (particle.startX + particle.h_v * timeSpan);
                //计算Y坐标
                int tempY = (int) (particle.startY + 4.9 * timeSpan * timeSpan + particle.v_v * timeSpan);

                //如果粒子超出屏幕下边沿
                if(tempY > 1920){
                    tempSet.remove(particle);
                    //重新设置粒子的个数
                    count = tempSet.size();
                }

                //修改粒子的坐标
                particle.x = tempX;
                particle.y = tempY;
            }

            //将时间延长
            time += span;
            try{
                Thread.sleep(sleepSpan);//休眠一段时间
            }catch (Exception e){
                e.printStackTrace();
            }
        }
    }
}   4、开发视图ParticleView类:
Java代码  package xiao.fuyan.particle;    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;    import java.util.ArrayList;    /**  * Created by xiao on 2017/2/10.  */  public class ParticleView extends SurfaceView implements SurfaceHolder.Callback {      //粒子的Y坐标超过该值就会从粒子集合中移出      public static final int DIE_OUT_LINE = 1920;      //后台刷新屏幕的线程      DrawThread dt = null;      //ParticleSet对象的引用      ParticleSet ps;      //ParticleThread对象的引用      ParticleThread pt;      //声明帧速率字符串      String fps = "FPS:N/A";        //构造器      public ParticleView(Context context){          super(context);          //添加callback接口          this.getHolder().addCallback(this);          //创建DrawThread对象          dt = new DrawThread(this, getHolder());          //创建ParticleSet对象          ps = new ParticleSet();          //创建ParticleThread对象          pt = new ParticleThread(this);      }        //绘制屏幕      public void doDraw(Canvas canvas){          //清除屏幕          canvas.drawColor(Color.BLACK);          //获取ParticleSet对象中的粒子          ArrayList<Particle> particleSet = ps.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;              int tempY = p.y;              int tempR = p.r;              //绘制该粒子              RectF oval = new RectF(tempX, tempY, tempX + 2 * tempR, tempY + 2 * tempR);              canvas.drawOval(oval, paint);          }            //设置画笔颜色          paint.setColor(Color.WHITE);          paint.setTextSize(60);          paint.setAntiAlias(true);          //画出帧速率字符串          canvas.drawText(fps, 900, 80, paint);      }        @Override      public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {        }        @Override      public void surfaceCreated(SurfaceHolder holder) {          //启动线程          if(!dt.isAlive()){              dt.start();          }          if(!pt.isAlive()){              pt.start();          }      }        @Override      public void surfaceDestroyed(SurfaceHolder holder) {          //停止线程          dt.flag = false;          dt = null;          pt.flag = false;          pt = null;      }  }  package xiao.fuyan.particle;

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;

import java.util.ArrayList;

/**
 * Created by xiao on 2017/2/10.
 */
public class ParticleView extends SurfaceView implements SurfaceHolder.Callback {
    //粒子的Y坐标超过该值就会从粒子集合中移出
    public static final int DIE_OUT_LINE = 1920;
    //后台刷新屏幕的线程
    DrawThread dt = null;
    //ParticleSet对象的引用
    ParticleSet ps;
    //ParticleThread对象的引用
    ParticleThread pt;
    //声明帧速率字符串
    String fps = "FPS:N/A";

    //构造器
    public ParticleView(Context context){
        super(context);
        //添加callback接口
        this.getHolder().addCallback(this);
        //创建DrawThread对象
        dt = new DrawThread(this, getHolder());
        //创建ParticleSet对象
        ps = new ParticleSet();
        //创建ParticleThread对象
        pt = new ParticleThread(this);
    }

    //绘制屏幕
    public void doDraw(Canvas canvas){
        //清除屏幕
        canvas.drawColor(Color.BLACK);
        //获取ParticleSet对象中的粒子
        ArrayList<Particle> particleSet = ps.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;
            int tempY = p.y;
            int tempR = p.r;
            //绘制该粒子
            RectF oval = new RectF(tempX, tempY, tempX + 2 * tempR, tempY + 2 * tempR);
            canvas.drawOval(oval, paint);
        }

        //设置画笔颜色
        paint.setColor(Color.WHITE);
        paint.setTextSize(60);
        paint.setAntiAlias(true);
        //画出帧速率字符串
        canvas.drawText(fps, 900, 80, paint);
    }

    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {

    }

    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        //启动线程
        if(!dt.isAlive()){
            dt.start();
        }
        if(!pt.isAlive()){
            pt.start();
        }
    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
        //停止线程
        dt.flag = false;
        dt = null;
        pt.flag = false;
        pt = null;
    }
}   5、开发DrawThread类:
Java代码  package xiao.fuyan.particle;    import android.graphics.Canvas;  import android.view.SurfaceHolder;    /**  * Created by xiao on 2017/2/10.  */  public class DrawThread extends Thread {      //ParticleView对象      ParticleView particleView;      //SurfaceHolder对象的引用      SurfaceHolder surfaceHolder;      //线程执行的标志位      boolean flag = false;      //休眠时间      int sleepSpan = 30;      //记录起始时间,用于计算帧速率      long start = System.nanoTime();      //记录帧数,      int count = 0;        //构造器      public DrawThread(ParticleView particleView, SurfaceHolder surfaceHolder){          this.particleView = particleView;          this.surfaceHolder = surfaceHolder;          this.flag = true;      }        @Override      //线程执行的方法,用于重绘屏幕和计算帧速率      public void run() {          Canvas canvas = null;          while(flag){              try{                  //获取ParticleView的画布                  canvas = surfaceHolder.lockCanvas(null);                  //加锁并且绘制                  synchronized (surfaceHolder){                      particleView.doDraw(canvas);                  }              }catch (Exception e){                  e.printStackTrace();              }finally {                  if(canvas != null){   //如果canvas不为空                      //surfaceHolder解锁,并将画布对象传回                      surfaceHolder.unlockCanvasAndPost(canvas);                  }              }                //如果计满20帧,计算帧速率              this.count++;              if(count == 20){                  count = 0;                  //获取当前时间                  long tempStamp = System.nanoTime();                  //获取时间间隔                  long span = tempStamp - start;;                  //为start重新赋值                  start = tempStamp;                  //计算帧速率                  double fps = Math.round(10000000000.0 / span * 20) / 100.0;                  //设置实时帧速率                  particleView.fps = "FPS" + fps;              }          }            try{              Thread.sleep(sleepSpan);          }catch (Exception e){              e.printStackTrace();          }      }  }  package xiao.fuyan.particle;

import android.graphics.Canvas;
import android.view.SurfaceHolder;

/**
 * Created by xiao on 2017/2/10.
 */
public class DrawThread extends Thread {
    //ParticleView对象
    ParticleView particleView;
    //SurfaceHolder对象的引用
    SurfaceHolder surfaceHolder;
    //线程执行的标志位
    boolean flag = false;
    //休眠时间
    int sleepSpan = 30;
    //记录起始时间,用于计算帧速率
    long start = System.nanoTime();
    //记录帧数,
    int count = 0;

    //构造器
    public DrawThread(ParticleView particleView, SurfaceHolder surfaceHolder){
        this.particleView = particleView;
        this.surfaceHolder = surfaceHolder;
        this.flag = true;
    }

    @Override
    //线程执行的方法,用于重绘屏幕和计算帧速率
    public void run() {
        Canvas canvas = null;
        while(flag){
            try{
                //获取ParticleView的画布
                canvas = surfaceHolder.lockCanvas(null);
                //加锁并且绘制
                synchronized (surfaceHolder){
                    particleView.doDraw(canvas);
                }
            }catch (Exception e){
                e.printStackTrace();
            }finally {
                if(canvas != null){   //如果canvas不为空
                    //surfaceHolder解锁,并将画布对象传回
                    surfaceHolder.unlockCanvasAndPost(canvas);
                }
            }

            //如果计满20帧,计算帧速率
            this.count++;
            if(count == 20){
                count = 0;
                //获取当前时间
                long tempStamp = System.nanoTime();
                //获取时间间隔
                long span = tempStamp - start;;
                //为start重新赋值
                start = tempStamp;
                //计算帧速率
                double fps = Math.round(10000000000.0 / span * 20) / 100.0;
                //设置实时帧速率
                particleView.fps = "FPS" + fps;
            }
        }

        try{
            Thread.sleep(sleepSpan);
        }catch (Exception e){
            e.printStackTrace();
        }
    }
}   6、开发程序MainActivity类:
Java代码  package xiao.fuyan.particle;    import android.app.Activity;  import android.os.Bundle;  import android.view.Window;  import android.view.WindowManager;      public class MainActivity extends Activity {        @Override      protected void onCreate(Bundle savedInstanceState) {          super.onCreate(savedInstanceState);          //设置不显示标题          requestWindowFeature(Window.FEATURE_NO_TITLE);          //设置全屏显示模式          getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,                  WindowManager.LayoutParams.FLAG_FULLSCREEN);            //创建一个ParticleView对象          ParticleView particleView = new ParticleView(this);          setContentView(particleView);        }  }  package xiao.fuyan.particle;

import android.app.Activity;
import android.os.Bundle;
import android.view.Window;
import android.view.WindowManager;


public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //设置不显示标题
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        //设置全屏显示模式
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
                WindowManager.LayoutParams.FLAG_FULLSCREEN);

        //创建一个ParticleView对象
        ParticleView particleView = new ParticleView(this);
        setContentView(particleView);

    }
}    

本文由职坐标整理并发布,希望对同学们有所帮助。了解更多详情请关注职坐标移动开发之Android频道!

本文由 @白羽 发布于职坐标。未经许可,禁止转载。
喜欢 | 0 不喜欢 | 0
看完这篇文章有何感觉?已经有0人表态,0%的人喜欢 快给朋友分享吧~
评论(0)
后参与评论

您输入的评论内容中包含违禁敏感词

我知道了

助您圆梦职场 匹配合适岗位
验证码手机号,获得海同独家IT培训资料
选择就业方向:
人工智能物联网
大数据开发/分析
人工智能Python
Java全栈开发
WEB前端+H5

请输入正确的手机号码

请输入正确的验证码

获取验证码

您今天的短信下发次数太多了,明天再试试吧!

提交

我们会在第一时间安排职业规划师联系您!

您也可以联系我们的职业规划师咨询:

小职老师的微信号:z_zhizuobiao
小职老师的微信号:z_zhizuobiao

版权所有 职坐标-一站式IT培训就业服务领导者 沪ICP备13042190号-4
上海海同信息科技有限公司 Copyright ©2015 www.zhizuobiao.com,All Rights Reserved.
 沪公网安备 31011502005948号    

©2015 www.zhizuobiao.com All Rights Reserved

208小时内训课程