Android 爆炸粒子动画-参考ExplosionField开源项目

来源:互联网 发布:曲靖医专网络管理系统 编辑:程序博客网 时间:2024/06/11 07:52

Android 爆炸粒子动画-参考ExplosionField开源项目

explosion开源项目地址:https://github.com/ChanJLee/ExplosionField

由于没有理解到explosionField开源项目里的粒子爆炸后运动曲线计算公式,我这里使用了贝塞尔曲线作为粒子运动轨迹

在我的APP中应用效果图如下:

这里写图片描述

以下为此动画的核心类,继承自ValueAnimator

粒子在动画时长内沿着贝塞尔曲线运动:

这里写图片描述

曲线由起点,终点,和控制点决定,计算公式为:

这里写图片描述

这里,P0为起点,P1为控制点,P2为终点,t为属性动画的属性值,在动画时长内由0-1变化。

package com.konka.peter.bookentry.lib;import android.animation.ValueAnimator;import android.graphics.Canvas;import android.graphics.Paint;import android.graphics.Rect;import android.view.View;import android.view.animation.AccelerateInterpolator;//我自己的工具类,这里只用到了dp与px单位换算方法import com.konka.peter.bookentry.util.Util;import java.util.Random;/** * 类描述 :自定义爆炸动画类,CircleView中使用 * @author 王春涛 * @version 1.0.0 */public class ExplosionAnimator extends ValueAnimator  {    //动画时长    private static final int DURATION=900;    //画笔    private Paint paint;    //所有爆炸后的粒子    private Particle[] particles;    //动画区域    private Rect rect;    //动画容器View    private View view;    //初始粒子数量num*num    private int num=6;    //每颗粒子半径    private static final float R= Util.dp2Px(2);    //随机变量    private Random random;    //粒子颜色    private int [] colors={0xf5f7fa,0xeaf2bf,0xf5f5eb,0xd1e69c,0xffffff};    public ExplosionAnimator(View view,Rect rect){        paint=new Paint();        this.rect=new Rect(rect);        //根据动画区域大小,计算粒子数量        num=Util.px2Dp(rect.right-rect.left)/12;        if(num<2){            num=2;        }        particles=new Particle[num*num];        random=new Random(System.currentTimeMillis());        //初始化粒子        for(int i=0;i<num;i++){            for(int j=0;j<num;j++){                int color=colors[random.nextInt(colors.length)];                particles[i*num+j]=initParticle(color);            }        }        this.view=view;        //设置动画取值范围        setFloatValues(0f,1f);        //动画速率曲线        setInterpolator(new AccelerateInterpolator(0.6f));        setDuration(DURATION);    }    /**     * 方法描述:   绘制每一颗粒子     * @param      canvas  画布     * @return     boolean     */    public boolean draw(Canvas canvas){        for (Particle particle:particles){            //根据当前属性值,定位粒子在贝塞尔曲线上的坐标,getAnimatedValue获取当前动画属性值            particle.update((float) getAnimatedValue());            //绘制粒子            if(particle.alpha>0f){                paint.setColor(particle.color);                paint.setAlpha((int) particle.alpha);                canvas.drawCircle(particle.x,particle.y,particle.r,paint);            }        }        //绘制完,刷新view显示,此时动画与父View之间实现了串联互动        view.invalidate();        return true;    } /**     * 方法描述:   动画开始,刷新页面     * @param           * @return          */    @Override    public void start() {        super.start();        view.invalidate();    }    /**     * 方法描述:   初始化一颗粒子     * @param      color 粒子颜色     * @return     Particle 粒子     */    public Particle initParticle(int color){        //自定义的粒子类        Particle particle=new Particle();        particle.color=color;        particle.r=R;        //start小于0.5,粒子向右运动,大于等于0.5,粒子向左运动        float start=random.nextFloat();        //粒子轨迹终点的随机偏移        float end=random.nextFloat();        //每颗粒子轨迹的起点都是固定的        particle.start_x=(rect.right+rect.left)/2;        particle.start_y=(rect.bottom+rect.top)/2;        //粒子终点则随机产生计算        if(start<0.5){       //向右            particle.end_x=(rect.right+rect.left)/2+(rect.right-rect.left)*end;            particle.end_y=rect.bottom+20*end;        }else {              //向左            particle.end_x=(rect.right+rect.left)/2-(rect.right-rect.left)*(1-end);            particle.end_y=rect.bottom-20*(1-end);        }        //贝塞尔曲线的控制点,由轨迹起点,终点以及0.7和3两个可变数决定        particle.control_x=particle.start_x+0.7f*(particle.end_x-particle.start_x);        particle.control_y=particle.start_y-3*random.nextInt((int) (particle.end_y-particle.start_y));        return particle;    }    /**     * 类描述:   一颗粒子的实体类     *     */    private class Particle{        //透明度        float alpha;        //颜色        int color;        //x坐标        float x;        //y坐标        float y;        //半径        float r;        //运行轨迹开始坐标        float start_x;        float start_y;        //运行轨迹结束坐标        float end_x;        float end_y;        //贝塞尔曲线控制点坐标        float control_x;        float control_y;        /**         * 方法描述:   初始化一颗粒子         * @param      index 此刻动画的属性值         * @return     Particle 粒子         */        public void update(float index){            //贝塞尔曲线计算此刻粒子坐标,根据贝塞尔曲线公式            x=(1-index)*(1-index)*start_x+2*index*(1-index)*control_x+index*index*end_x;            y=(1-index)*(1-index)*start_y+2*index*(1-index)*control_y+index*index*end_y;            //透明度            if(index<0.8){                alpha=255;            }else {                alpha=255*(-5*index+5);            }        }    }}

接下来我们在一个自定义View里面使用以上动画:

package com.konka.peter.bookentry.lib;import android.animation.Animator;import android.content.Context;import android.content.Intent;import android.graphics.Canvas;import android.graphics.Rect;import android.view.View;/** * 类描述 :自定义View * @author 王春涛 * @version 1.0.0 */public class CircleView extends View {    //粒子爆炸动画    private  ExplosionAnimator explosionAnimator;    public CircleView(Context context) {        super(context);        //动画开始        startExplosionAnim();    }    public CircleView(Context context, AttributeSet attrs) {        super(context, attrs);        //动画开始        startExplosionAnim();    }    public CircleView(Context context, AttributeSet attrs, int defStyleAttr) {        super(context, attrs, defStyleAttr);        //动画开始        startExplosionAnim();    }    /**     * 方法描述:   重写绘制方法,在这里绘制爆炸过程的每一帧     * @param      canvas 画布     * @return     void     *     */    @Override    protected void onDraw(Canvas canvas) {        super.onDraw(canvas);        explosionAnimator.draw(canvas);    }    private void startExplosionAnim(){        //动画显示区域        Rect rect=new Rect(0,0,200,200);        explosionAnimator=new ExplosionAnimator(this,rect);        explosionAnimator.start();    }}
0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 不想去德育基地怎么办? 小学一年级成绩不好怎么办 初中军训来月经怎么办 ie网页无响应怎么办 ie9浏览器无响应怎么办 电脑没ie浏览器怎么办 ie浏览器删掉了怎么办 素质拓展分不够怎么办 想承包学校军训怎么办 军训完晒黑了怎么办 完美动力忽悠人怎么办 wlan密码忘了怎么办 孩子多动怎么办呢 孩子性格太内向怎么办 孩子脾气暴躁易怒怎么办 小孩有点叛逆应怎么办 小孩太叛逆怎么办关住 对不听话的孩子怎么办 孩子在学校不听话怎么办 孩子叛逆不回家怎么办 孩子厌学怎么办青春期叛逆 孩子青春期叛逆家长怎么办 孩子老哭不听话怎么办 8岁宝宝不听话怎么办 儿孑不听话叛逆怎么办 孩子太小不听话怎么办 得了只有很紧张怎么办 内向的妈妈孩子怎么办 对孩子没有耐心怎么办 孩子心理有问题怎么办 孩子心里有问题怎么办 父母打架我该怎么办 爸爸妈妈要离婚怎么办 父母吵架怎么办动手了 父母因为钱吵架怎么办 父母吵架孩子该怎么办 特别倔强的孩子怎么办 孩子胆小不自信怎么办 孩子不自信家长怎么办 二年级孩子厌学怎么办 儿童注意力不集中怎么办