Android实现粒子烟花爆炸效果
一、每一个粒子都是一个实体,有自己的属性,所以需要定义一个实体类:
/**
* 上升粒子
*/
public class ParticalBean {
//画笔
private Paint paint;
//x位置
private int x;
//y位置
private int y;
//速率
private int speed;
//移动距离
private int distance;
//是否爆炸
private boolean isBoom;
//爆炸后粒子数据
private List<BoomParicalBean> boomParicalBeans;
public ParticalBean(Paint paint, int x, int y, int speed, int distance) {
this.paint = paint;
this.x = x;
this.y = y;
this.speed = speed;
this.distance = distance;
}
public Paint getPaint() {
return paint;
}
public void setPaint(Paint paint) {
this.paint = paint;
}
public int getDistance() {
return distance;
}
public void setDistance(int distance) {
this.distance = distance;
}
public int getX() {
return x;
}
public void setX(int x) {
this.x = x;
}
public int getY() {
return y;
}
public void setY(int y) {
this.y = y;
}
public int getSpeed() {
return speed;
}
public void setSpeed(int speed) {
this.speed = speed;
}
public boolean isBoom() {
return isBoom;
}
public void setBoom(boolean boom) {
isBoom = boom;
}
public List<BoomParicalBean> getBoomParicalBeans() {
return boomParicalBeans;
}
public void setBoomParicalBeans(List<BoomParicalBean> boomParicalBeans) {
this.boomParicalBeans = boomParicalBeans;
}
}
/**
* 爆炸粒子
*/
public class BoomParicalBean {
//x位置
private int x;
//y位置
private int y;
//速率
private int speed;
//移动距离
private int distance;
//粒子半径
private int raduis;
public BoomParicalBean(int x, int y, int raduis, int speed, int distance) {
this.x = x;
this.y = y;
this.raduis = raduis;
this.speed = speed;
this.distance = distance;
}
public int getX() {
return x;
}
public void setX(int x) {
this.x = x;
}
public int getY() {
return y;
}
public void setY(int y) {
this.y = y;
}
public int getRaduis() {
return raduis;
}
public void setRaduis(int raduis) {
this.raduis = raduis;
}
public int getSpeed() {
return speed;
}
public void setSpeed(int speed) {
this.speed = speed;
}
public int getDistance() {
return distance;
}
public void setDistance(int distance) {
this.distance = distance;
}
}
/**
* 粒子工厂
*/
class ParticalFactory {
/** 生成上升粒子
* @param paint
* @param x
* @param y
* @param speed
* @param distance
* @return
*/
static ParticalBean createPartical(Paint paint, int x, int y, int speed, int distance){
return new ParticalBean(paint, x, y, speed, distance);
}
/** 生成爆炸粒子
* @param x
* @param y
* @param raduis
* @param speed
* @param distance
* @return
*/
static BoomParicalBean createBoomPartical(int x, int y, int raduis, int speed, int distance){
return new BoomParicalBean(x, y, speed, raduis, distance);
}
}
gestureDetector = new GestureDetector(getContext(), new GestureDetector.SimpleOnGestureListener(){
@Override
public boolean onDown(MotionEvent e) {
ViewCompat.postInvalidateOnAnimation(ParticalView.this);
list.add(ParticalFactory.createPartical(cratePaint(), (int) e.getX(), (int)e.getY(), (int) (Math.random() * (15-5)+5), (int) (Math.random() * 1000)));
return true;
}
});
for (ParticalBean particalBean : list) {
if(!particalBean.isBoom()){
canvas.drawCircle(particalBean.getX(), particalBean.getY(), 50, particalBean.getPaint());
particalBean.setY(particalBean.getY() - particalBean.getSpeed());
}
}
for (int i=0; i<list.size(); i++){
ParticalBean particalBean = list.get(i);
if(!particalBean.isBoom()){
if (particalBean.getY() <= particalBean.getDistance()){
//碎片个数
int fragments = (int) (Math.random() * (100 - 60) + 60);
List<BoomParicalBean> boomParicalBeans = new ArrayList<>();
for (int j=0; j < fragments ;j++){
double angle = (j * 2 * Math.PI) / fragments;
int raduis = (int) (Math.random() * fragmentsRaduis);
int x = (int) (Math.cos(angle) * raduis) + particalBean.getX();
int y = (int) (Math.sin(angle) * raduis) + particalBean.getY();
BoomParicalBean boomPartical = ParticalFactory.createBoomPartical(x, y, boomParicalSpeed, (int) (Math.random() * particalRaduis), y + boomParticalMoveY);
boomParicalBeans.add(boomPartical);
}
particalBean.setBoomParicalBeans(boomParicalBeans);
particalBean.setBoom(true);
}
}
}
//爆炸粒子
for (int p=0; p< list.size(); p++){
ParticalBean particalBean = list.get(p);
if(particalBean.isBoom()){
List<BoomParicalBean> boomParicalBeans = particalBean.getBoomParicalBeans();
for (int i=0; i<boomParicalBeans.size() ;i++){
BoomParicalBean boomParicalBean = boomParicalBeans.get(i);
canvas.drawCircle(boomParicalBean.getX(), boomParicalBean.getY(), boomParicalBean.getRaduis(), particalBean.getPaint());
boomParicalBean.setY(boomParicalBean.getY() + boomParicalBean.getSpeed());
if(boomParicalBean.getY() >= boomParicalBean.getDistance()){
boomParicalBeans.remove(boomParicalBean);
}
if(boomParicalBeans.isEmpty()){
list.remove(particalBean);
ViewCompat.postInvalidateOnAnimation(ParticalView.this);
}
}
}
}
评论