android 粒子爆炸特效
先上图:
这是一个高级UI特效,是个动画。
完成这个动画只要3步:
1、控件完成振动效果动画。
2、控件振动动画完成后消失,然后将控件转换成Bitmap.
3、Bitmap完成粒子爆炸特效。
其实完成粒子爆炸特效的并不是控件View本身,而是Bitmap,将Bitmap分割成多个小球,小球在x轴上随机地左右晃动,在y轴上径直下落就行了。
代码介绍:
Particle:
public abstract class Particle {float x;float y;int color;public Particle(float x, float y, int color) {this.x = x;this.y = y;this.color = color;}//计算protected abstract void compute(float factor);//绘制protected abstract void draw(Canvas canvas,Paint paint);//逐步绘制protected void draw(Canvas canvas,Paint paint,float factor){compute(factor);draw(canvas,paint);}
}
这是一个粒子的抽象类,用于定义粒子的x,y坐标,颜色,计算x,y坐标的方法,绘制方法以及一个将这2个方法封装起来的新方法.
FallingParticle
public class FallingParticle extends Particle {private static final String TAG = "FallingParticle";private float radius = FallingParticleFactory.PART_WH; //粒子半径private float alpha = 1.0f; //透明度private Rect mBound;public FallingParticle(float x, float y, int color,Rect bound) {super(x, y, color);mBound = bound;}@Overrideprotected void compute(float factor) {x = x + factor * Utils.RANDOM.nextInt(mBound.width()) * (Utils.RANDOM.nextFloat() - 0.5f); y = y + factor * Utils.RANDOM.nextInt(mBound.height() / 2); radius = radius - factor * Utils.RANDOM.nextInt(2); alpha = (1 - factor) * (1 + Utils.RANDOM.nextFloat()); }@Overrideprotected void draw(Canvas canvas, Paint paint) {paint.setColor(color);paint.setAlpha((int) (Color.alpha(color) * alpha));canvas.drawCircle(x,y,radius,paint);}
}
继承抽象方法Particle,主要具体计算粒子的x、y坐标,半径,透明度,具体算法如下:
x = x +(0-1↑) × [-0.5width,0.5width] ():表示从从0到1逐步上升的数,[]:表示这个区间内的任意一个随机数(下同)
y = y + (0-1↑) × [0,0.5h]
radius = radius - (0-1↑) × [0,2]
alpha = [0-1↓] × (1 + [0,1])
粒子工厂抽象方法
public abstract class ParticleFactory {protected abstract Particle[][] generateParticles(Bitmap bitmap, Rect bound);
}
用于生成粒子矩阵,只有一个方法用来生成所有粒子
粒子工厂
public class FallingParticleFactory extends ParticleFactory {private static final String TAG = "FallingParticleFactory";public static final int PART_WH = 8; //粒子默认宽高@Overrideprotected Particle[][] generateParticles(Bitmap bitmap, Rect bound) {int w = bound.width();int h = bound.height();Log.d(TAG, "generateParticles: " + bound.left + "," + bound.top);int partW_count = w / PART_WH; //横向个数int partH_count = h / PART_WH; //竖向个数//判断个数是否小于1,这种情况是控件的大小 < 8partW_count = partW_count > 1 ? partW_count : 1;partH_count = partH_count > 1 ? partH_count : 1;int bitmap_part_w = bitmap.getWidth() / partW_count;int bitmap_part_h = bitmap.getHeight() / partH_count;Particle[][] particles = new Particle[partH_count][partW_count];for (int row = 0; row < partH_count; row++) {for (int column = 0; column < partW_count; column++) {//取得当前粒子所在位置颜色int color = bitmap.getPixel(column * bitmap_part_w,row * bitmap_part_h);float x = bound.left + column * PART_WH;float y = bound.top + row * PART_WH;particles[row][column] = new FallingParticle(x,y,color,bound);}}return particles;}
}
将一张Bitmap分割成多个粒子,每个粒子的宽、高为8(这个可以自己设定),Rect是包裹这个View的外围矩形,通过它的宽、高除以粒子的宽高后就可以得到每行有多少粒子,一共有多少行。
ExplosionField
public class ExplosionField extends View {private static final String TAG = "ExplosionField";private List<ExplosionAnimator> explosionAnimators;private OnClickListener onClickListener;public ExplosionField(Context context) {super(context);explosionAnimators = new ArrayList<>();//将动画区域添加到界面上attachToActivity();}private void attachToActivity() {//content是一个帧布局ViewGroup rootView = ((Activity) getContext()).getWindow().getDecorView().findViewById(android.R.id.content);ViewGroup.LayoutParams params = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);rootView.addView(this,params);}/*** 添加需要有粒子特效的View* @param view*/public void addListener(View view){if(view instanceof ViewGroup){ViewGroup viewGroup = (ViewGroup) view;int viewCount = viewGroup.getChildCount();for (int i = 0; i < viewCount; i++) {addListener(viewGroup.getChildAt(i));}}else{view.setOnClickListener(getOnClickListener());}}public OnClickListener getOnClickListener(){if(onClickListener == null){onClickListener = new OnClickListener() {@Overridepublic void onClick(View v) {explode(v);}};}return onClickListener;}//执行爆炸特效public void explode(final View view){final Rect rect = new Rect();view.getGlobalVisibleRect(rect); //获取View相对整个屏幕的位置//标题栏高度int titleHeight = ((ViewGroup) getParent()).getTop();//状态栏高度Rect frame = new Rect();((Activity) getContext()).getWindow().getDecorView().getWindowVisibleDisplayFrame(frame);int statusBarHeight = frame.top;//相对整个屏幕的位置-标题栏(actionBar)的高度-状态栏的高度rect.offset(0,-titleHeight-statusBarHeight);if(rect.width() == 0 || rect.height() == 0){return;}//震动动画ValueAnimator animator = ValueAnimator.ofFloat(0f,1f).setDuration(150);animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {@Overridepublic void onAnimationUpdate(ValueAnimator animation) {view.setTranslationX((Utils.RANDOM.nextFloat() - 0.5f) * view.getWidth() * 0.05f);view.setTranslationY((Utils.RANDOM.nextFloat() - 0.5f) * view.getHeight() * 0.05f);}});animator.addListener(new AnimatorListenerAdapter() {@Overridepublic void onAnimationEnd(Animator animation) {super.onAnimationEnd(animation);explode(view,rect);}});animator.start();}private void explode(final View view,Rect bound){final ExplosionAnimator explosionAnimator = new ExplosionAnimator(this,Utils.createBitmapFromView(view),bound);explosionAnimators.add(explosionAnimator);explosionAnimator.addListener(new AnimatorListenerAdapter() {@Overridepublic void onAnimationStart(Animator animation) {view.setClickable(false);//缩小透明view.animate().setDuration(150).scaleX(0f).scaleY(0f).alpha(0f).start();}@Overridepublic void onAnimationEnd(Animator animation) {view.setClickable(true);//放大view.animate().setDuration(150).scaleX(1f).scaleY(1f).alpha(1f).start();explosionAnimators.remove(explosionAnimator);}});explosionAnimator.start();}@Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);for (ExplosionAnimator explosionAnimator : explosionAnimators) {explosionAnimator.draw(canvas);}}
}
动画执行区域(其实是个View),首先将添加动画的控件设置点击监听器,如果这个控件是个ViewGroup,那么将它所有的子View设置点击监听器。紧接着执行振动动画,结束后执行粒子爆炸特效。
ExplosionAnimator
public class ExplosionAnimator extends ValueAnimator {private static final String TAG = "ExplosionAnimator";public static final int DEFAULT_DURATION = 1500; //动画默认持续时间private Particle[][] mParticles; //粒子们private ParticleFactory mParticleFactory; //粒子工厂private View mContainer; //动画执行区域private Paint mPaint;public ExplosionAnimator(View view, Bitmap bitmap, Rect bound) {mParticleFactory = new FallingParticleFactory();mPaint = new Paint();setFloatValues(0f,1f);setDuration(DEFAULT_DURATION);mParticles = mParticleFactory.generateParticles(bitmap,bound);mContainer = view;}public void draw(Canvas canvas){if(!isStarted()){//动画结束return;}//所有粒子开始运动for (Particle[] mParticle : mParticles) {for (Particle particle : mParticle) {particle.draw(canvas,mPaint,(float) getAnimatedValue());}}mContainer.invalidate();}@Overridepublic void start() {super.start();mContainer.invalidate();Log.d(TAG, "start: ");}
}
粒子爆炸动画实现类,继承于ValueAnimator,在draw方法中,遍历所以粒子并调用他们的draw方法,完成下一帧的绘制,值得注意的是,下方的invalidate方法会强制ExplosionField重绘,如图:
首先在ExplosionField中调用ExplosionAnimator的start方法,start方法中会使用invalidate方法来使ExplosionField重绘(调用onDraw方法),onDraw方法调用draw方法,draw方法中也使用invalidate,每一次循环完成一次重绘,整个动画就慢慢完成了。
demo地址:https://github.com/lyx19970504/Particle_Effect
android 粒子爆炸特效相关推荐
- Android粒子爆炸特效[可用于任意控件]
小米手机用户可以看到,小米手机在应用卸载时会有一个粒子爆炸的特效效果,对此类动画效果垂涎已久,奈何一直没有机会用.正好最近项目里需要用到粒子爆炸的特效,于是便抽时间自己也试着仿写了一个效果出来. 先看 ...
- Android UI - 粒子爆炸特效
Android UI - 粒子爆炸特效 效果 实现 分析 关键代码 源码 效果 实现 分析 首先动画效果需要在一个位于顶层的view上绘制,目的是不被其他控件遮挡. 添加点击事件,触发后给控件加一个抖 ...
- Android制作粒子爆炸特效
简介 最近在闲逛的时候,发现了一款粒子爆炸特效的控件,觉得比较有意思,效果也不错. 但是代码不好扩展,也就是说如果要提供不同的爆炸效果,需要修改的地方比较多.于是我对源代码进行了一些重构,将爆炸流程和 ...
- Android 粒子爆炸效果,可以给任意 view 添加该效果
ViewExplosion 项目地址:835127729/ViewExplosion 简介:Android 粒子爆炸效果,可以给任意 view 添加该效果 更多:作者 提 Bug 官网 ...
- MOGRT 金色粒子爆炸特效logo展示pr片头模板mogrt
这是一个PR动态图形模板Mogrt,金色粒子爆炸特效logo展示PR片头模板mogrt.具有粒子效果的组合,这些效果结合在一起以显示和增强您的媒体. 此模板包含 1 个logo占位符和 1 个可编辑文 ...
- three.js 实现图片粒子爆炸特效
大家好,这里是 CSS 魔法使--alphardex. 以下是最终实现的效果图 撒,哈吉马路由! 准备工作 笔者的three.js模板:点击右下角的fork即可复制一份 世界同步 在我的上一篇博文中, ...
- 使用opengl实现爆炸特效
原理是用点阵展示图片,将点阵传给glsl里面的噪音方法更改位置. 图像对象 储存顶点数据 这里我设置了顶点数据和图片的顶点数据传入,因为顶点和图片的点阵不一样分开储存. public class Po ...
- AE484 3D大气电影风格LOGO视频片头爆炸烟雾粒子碎片特效动画制作ae模板
AE484 3D大气电影风格LOGO视频片头爆炸烟雾粒子碎片特效动画制作ae模板 模板用途:3D,动作,电影,云,史诗,爆炸,火灾,灯光,标志揭示,金属,神秘,粒子,反射,烟雾 软件版本:后效CS6~ ...
- Android游戏开发–粒子爆炸
有没有想过爆炸是如何产生的? 让我们绕个弯路,尝试实现基本的粒子爆炸. 爆炸不过是一堆散布在屏幕上的,源自单个点的粒子(无论是像素,小形状还是图像). 为了方便起见,并非总是如此,而是为了简洁起见,我 ...
最新文章
- h.265编码库x265实例
- db2 参数标识符使用无效_在Python应用程序中使用配置的最佳实践
- boost::mp11::mp_set_contains相关用法的测试程序
- @bean注解和@component注解的区别_通过源码查看 @Component,@Service 等注解是如何被解析的...
- html 文件上传与移除,Vue采用input实现文件上传与删除
- Oracle HTTP 乱码
- ARC075 F.Mirrored
- VS2013密钥(所有版本)
- segue跳转_使用SwiftUI的Segue Shenanigans
- python pip安装镜像源
- 消防联动控制系统服务器,火灾自动报警消防联动控制系统报价单V4.4.xls
- 基于MATLAB与Python计算长时间遥感栅格图像的像元值变异系数(CV)
- bitblt和getpixel哪个更效率
- 1.1 芯片研究背景及意义
- eclipse建maven项目报: Could not resolve archetype org.apache.maven.archetypes:maven-archetype-webapp:1.0
- [FFmpeg]编译av1的dav1d解码库
- P4850 [IOI2009]葡萄干raisins 记忆化搜索
- python中的pygame弹球游戏代码_python pygame实现挡板弹球游戏
- 【三维目标分类 】PointNet详解(一)
- 2-1径向基神经网络(RBF)代码