摘要:本文将带你了解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频道!
您输入的评论内容中包含违禁敏感词
我知道了
请输入正确的手机号码
请输入正确的验证码
您今天的短信下发次数太多了,明天再试试吧!
我们会在第一时间安排职业规划师联系您!
您也可以联系我们的职业规划师咨询:
版权所有 职坐标-一站式IT培训就业服务领导者 沪ICP备13042190号-4
上海海同信息科技有限公司 Copyright ©2015 www.zhizuobiao.com,All Rights Reserved.
沪公网安备 31011502005948号