Android烟花效果(SurfaceView实现)
来源:互联网 发布:linux yum网络安装 编辑:程序博客网 时间:2024/05/16 14:53
烟花效果搜出来好像很多,但是没有太好的例子,于是自己做了一个效果,仅仅是完成了定制的需求。看下效果:
效果是,一个气泡抛物线出来,然后爆开。大致跟上次分享的点赞特效差不多,仅仅是根据需求绘制不同的效果:SurfaceView实现点赞效果
把相同代码去掉了,要直接用的话拼接一下吧,这里主要是说一下绘制过程
/** * 直播页面点赞特效,采用SurfaceView绘制 * 与普通控件使用方法类似,点赞是只需要调用startBomb()即可 */public class BombView extends SurfaceView implements SurfaceHolder.Callback { private static final int MAX_BUBBLE_COUNT = 90; private SurfaceHolder mHolder; private DrawTask mDrawTask; // 绘制UI的线程 private Paint mPaint; // 绘制需要使用的画刷 private FuseView mFuseView; // 引导的view private boolean mIsDismiss = false; //是否处于消失阶段 private int mWidth; // 控件的宽度 private int mHeight; // 控件的高度 private int mBombX; // 旋转的中心X private int mBombY; // 旋转的中心Y private int dx = 0; // 引导view在坐抛物线运动时在x轴的增量 private Bitmap[] mDrawables; // 存放需要展示的图 private int[] mDrawableResIDs; // 存放需要展示的图 private List<Bubble> mBubbles = Collections.synchronizedList(new LinkedList<Bubble>()); // 用于存放点赞信息 private Random mRandom = new Random(); // 用于产生随机数 public BombView(Context context, AttributeSet attrs) { super(context, attrs); mHolder = getHolder(); mHolder.addCallback(this); mHolder.setKeepScreenOn(true); mHolder.setFormat(PixelFormat.TRANSPARENT); mPaint = new Paint(); mDrawableResIDs = new int[] { R.drawable.praise_eight, R.drawable.praise_one, R.drawable.praise_third, R.drawable.praise_two, R.drawable.praise_five, R.drawable.praise_four, R.drawable.praise_seven, R.drawable.praise_six, }; mDrawables = new Bitmap[mDrawableResIDs.length]; } @Override protected void onDraw(final Canvas canvas) { if (canvas != null) { canvas.drawColor(Color.TRANSPARENT, Mode.CLEAR); // 清空界面 if (mFuseView == null) { return; } if (mFuseView.y+mFuseView.bitmap.getHeight()/2 > mBombY) { mPaint.setAlpha(255); if (mFuseView.x+mFuseView.bitmap.getWidth()/2 > mWidth/2) { // 抛物线 mFuseView.scale = dx*1.5f/mWidth + 1f; canvas.save(); mFuseView.x = mWidth*7/8 - dx; mFuseView.y = (int) getY(dx); canvas.scale(mFuseView.scale, mFuseView.scale, mFuseView.x+mFuseView.bitmap.getWidth()/2, mFuseView.y+mFuseView.bitmap.getHeight()/2); canvas.drawBitmap(mFuseView.bitmap, mFuseView.x, mFuseView.y, mPaint); canvas.restore(); dx += dip2px(4); } else { // 直线上升 canvas.save(); canvas.scale(mFuseView.scale, mFuseView.scale, mFuseView.x+mFuseView.bitmap.getWidth()/2, mFuseView.y+mFuseView.bitmap.getHeight()/2); canvas.drawBitmap(mFuseView.bitmap, mFuseView.x, mFuseView.y, mPaint); canvas.restore(); mFuseView.y -= dip2px(5); } postDelayed(mDrawTask, 5); } else { if (!mIsDismiss) { mIsDismiss = mBubbles.size() > 0 && mBubbles.get(0).top < mWidth*9/20; } for (int i=mBubbles.size()-1; i>=0; i--) { // 绘制气泡 drawBubble(canvas, mBubbles.get(i)); } // 大爱心放大消失 mFuseView.x = mBombX - mFuseView.bitmap.getWidth()/2; mFuseView.y = mBombY - mFuseView.bitmap.getHeight()/2; mFuseView.scale += 0.2; mFuseView.alpha = (int)((5-mFuseView.scale)*85);// ps:85 = 255/3 根据缩放倍数来计算透明度 if (mFuseView.alpha > 0) { mPaint.setAlpha(mFuseView.alpha); canvas.save(); canvas.scale(mFuseView.scale, mFuseView.scale, mBombX, mBombY); canvas.drawBitmap(mFuseView.bitmap, mFuseView.x, mFuseView.y, mPaint); canvas.restore(); } if (mBubbles.size() > 0) { postDelayed(mDrawTask, 10); } else { release(); } } } } private void drawBubble(Canvas canvas, Bubble bubble) { if (bubble.top + bubble.bitmap.getHeight()/2 > mWidth/2) { bubble.top = bubble.top - dip2px(2); return; } if (mIsDismiss) { bubble.alpha -= 12; if (bubble.alpha < 0) { mBubbles.remove(bubble); return; } } bubble.top -= dip2px(0.5f); if (bubble.scale < 1.2f) { bubble.scale += 0.015f; } mPaint.setAlpha(bubble.alpha); canvas.save(); canvas.scale(bubble.scale, bubble.scale, bubble.left+bubble.bitmap.getWidth()/2, bubble.top+bubble.bitmap.getHeight()/2); canvas.rotate(bubble.rotate, mBombX, mBombY); canvas.drawBitmap(bubble.bitmap, bubble.left, bubble.top, mPaint); canvas.restore(); } /** * 开始绘制爆炸彩蛋,如果上一个效果还没结束,则不处理新的 */ public void startBomb() { if (mFuseView != null) { return; } initFuseView(); generateBubble(MAX_BUBBLE_COUNT); dx = 0; mIsDismiss = false; post(mDrawTask); } /** * 初始化引导 */ private void initFuseView() { mFuseView = new FuseView(); mFuseView.x = mWidth*7/8; mFuseView.y = mHeight*17/20; mFuseView.bitmap = BitmapUtil.readBitmap(getResources(), R.drawable.praise_five); } /** * 添加点赞,会对传入的个数进行处理 * @param count */ private void generateBubble(int count) { for (int i = 0; i < count; i++) { Bubble bubble = new Bubble(); bubble.bitmap = getRandBitmap(); bubble.alpha = 155 + mRandom.nextInt(100); bubble.scale = 0.6f + mRandom.nextFloat()*0.4f;// bubble.rotate = mRandom.nextInt(360); bubble.rotate = 360*i/count; // 由于绘制时还需要缩放,不然可以使用增量旋转,即不用每次都restore if (bubble.rotate > 180) { // 反向旋转 bubble.rotate = bubble.rotate - 360; } bubble.left = mWidth/2 - bubble.bitmap.getWidth()/2; float offset = 0; if (i % 2 == 0) { offset = mWidth*0.1f + mWidth*0.15f * i/count; } if (i%3 == 0) { offset = mWidth*0.25f + mWidth*0.15f * i/count; } if (i%5 == 0) { offset = mWidth*0.4f + mWidth*0.12f * mRandom.nextFloat(); } bubble.top = offset - bubble.bitmap.getHeight(); mBubbles.add(0, bubble); } mBubbles.get(0).top = mWidth*0.52f - dip2px(5); // 以第一个气泡的位置判断是否该dismiss mBubbles.get(0).alpha = 1; // 防止正在消失时突然显现出来 } @Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { this.mWidth = width; this.mHeight = height; mBombX = mWidth/2; mBombY = mWidth/2; } class Bubble { public Bitmap bitmap; public float scale = 1.0f; // 缩放 public float top = 0f; // 偏移 public float left = 0f; // 偏移 public int rotate = 0; // 旋转 public int alpha = 255; // 透明度 public Bubble() { this.bitmap = getRandBitmap(); } } class FuseView { public Bitmap bitmap; public float scale; public int alpha; public int x; public int y; } // 抛物线 private float getY(float x) { return mHeight*10/11 - 0.009f * x * x; } public void release() { mFuseView = null; // 防止过度绘制 for (Bitmap bitmap : mDrawables) { if (bitmap != null && !bitmap.isRecycled()) { bitmap.recycle(); } } }}
代码链接:https://github.com/brian512/AndroidDemo
我写的编程博客客户端介绍:http://blog.csdn.net/brian512/article/details/51558809
点击查看应用详情
0 0
- Android烟花效果(SurfaceView实现)
- android实现烟花效果
- android利用图片实现烟花效果
- powershell 实现烟花效果
- android 放烟花效果
- Android EditText 添加烟花效果
- android采用SurfaceView实现文字滚动效果
- 烟花效果
- 烟花效果
- 烟花效果
- 粒子系统-烟花效果的实现
- Android开发——为EditText添加烟花效果的实现
- Android应用程序入门 推箱子游戏开发(一) surfaceView 实现动画效果
- Android动画学习(六)之View揭露效果和SurfaceView实现动画
- Android使用SurfaceView实现墨迹天气的风车效果
- Android使用SurfaceView实现墨迹天气的风车效果
- Android使用SurfaceView实现墨迹天气的风车效果
- Android自定义view--SurfaceView实现墨迹天气的风车效果
- 【Boost】boost库的随机数的例子
- Spring 依赖注入
- [ATL/WTL]_[初级]_[关于CEdit不识别WM_KEYDOWN的问题]
- 【TRIO-Basic从入门到精通教程五】直线、圆弧插补的指令使用
- HDOJ_Prime Ring Problem
- Android烟花效果(SurfaceView实现)
- 6/14 筑个窝
- WPF实现MDI窗体
- ajax_思维导图简单总结
- 法线贴图
- Java设计模式-Proxy代理模式
- Solr入门之官方文档6.0阅读笔记系列(六) 第三部分开始
- oxygen 文档的生成和管理
- 关于sizeof在调用函数中获取被调函数数组长度的思考