自定义View 实现 刮刮卡效果和美女撕衣服
来源:互联网 发布:sqlserver触发器实例 编辑:程序博客网 时间:2024/05/17 01:47
直奔高潮,不对,直奔主题。
效果图:
下面上代码:
public class TearView extends View { private Paint paint,paintB; private Canvas canva; private Bitmap bf; private Path path; private int width, height; public TearView(Context context, AttributeSet attrs) { super(context, attrs); init(); } private void init() { //设置画笔的基本参数 path = new Path(); paint = new Paint(); paint.setAntiAlias(true); //橡皮擦效果 必须设置透明度为0 才有效 paint.setAlpha(0); paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN)); paint.setStrokeWidth(10); paint.setStrokeCap(Paint.Cap.ROUND); paint.setStrokeJoin(Paint.Join.ROUND); //简单的设置下 中奖文字画笔 paintB = new Paint(); paintB.setColor(Color.RED); paintB.setAntiAlias(true); paintB.setTextSize(26); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); width = MeasureSpec.getSize(widthMeasureSpec); height = MeasureSpec.getSize(heightMeasureSpec); //这里在布局设置了参数,只是为了显示效果,所以偷懒,不调用setMeasuredDimension()方法了 bf = Bitmap.createBitmap(width,height, Bitmap.Config.ARGB_8888); canva = new Canvas(bf); canva.drawColor(Color.GRAY); } @Override public boolean onTouchEvent(MotionEvent event) { //记录滑动的路线 switch (event.getAction()) { case MotionEvent.ACTION_DOWN: path.moveTo(event.getX(), event.getY()); break; case MotionEvent.ACTION_MOVE: path.lineTo(event.getX(), event.getY()); break; } canva.drawPath(path, paint); invalidate(); return true; } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); canvas.drawText("一等奖",width/3,height/2,paintB); canvas.drawBitmap(bf, 0, 0, null); }
PorterDuffXfermode 控制的是两个图像的混合模式。一共有16中模式,而达到刮刮卡的效果,用到的就是其中的一种:PorterDuff.Mode.DST_IN,具体效果可以参考官网的API示例图。
dst是先画的图形,src是后画的图形。平时用的最多的就是,用一张图片作为另一张图片的遮罩层,然后通过控制遮罩层,来控制下面的图形的显示效果,对于上面的例子,灰色的图层,就是遮罩层,在上面使用”橡皮擦”,整天效果就变成刮刮卡了。
画图功能的橡皮擦,也可以用到上面的混合模式。
public class PaintView extends View{ public Paint paint; private Canvas canva; private Path path; private Bitmap bitmap; public PaintView(Context context, AttributeSet attrs) { super(context, attrs); init(context); } private void init(Context context){ paint = new Paint(); paint.setStrokeWidth(30); paint.setColor(Color.BLUE); paint.setStyle(Paint.Style.STROKE); paint.setAntiAlias(true); paint.setStrokeCap(Paint.Cap.ROUND); paint.setStrokeJoin(Paint.Join.ROUND); path = new Path(); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); bitmap = Bitmap.createBitmap(MeasureSpec.getSize(widthMeasureSpec),MeasureSpec.getSize(heightMeasureSpec), Bitmap.Config.ARGB_8888); canva = new Canvas(bitmap); } @Override public boolean onTouchEvent(MotionEvent event) { switch (event.getAction()){ case MotionEvent.ACTION_DOWN: path.moveTo(event.getX(),event.getY()); break; case MotionEvent.ACTION_MOVE: path.lineTo(event.getX(), event.getY()); break; case MotionEvent.ACTION_UP: path.reset(); break; } canva.drawPath(path,paint); invalidate(); return true; } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); canvas.drawColor(Color.WHITE); canvas.drawBitmap(bitmap,0,0,null); }
使用橡皮擦功能时,修改paint即可。
效果图:
paint.setStyle(Paint.Style.STROKE); paint.setAlpha(0); paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN)); paint.setStrokeJoin(Paint.Join.ROUND); paint.setStrokeWidth(30); paintView.setPaint(paint);
这让我想起了以前玩的 “美女撕衣服” 游戏,咳咳,不对,是研究。其实也是两张图片用这张模式混合,然后”撕”掉她们的衣服。
哈哈,先上效果图:
这次不用View,而是换成SurfaceView,因为View是通过刷新重新绘制,刷新的间隔事件是16ms,也就是1000/16,一秒60桢,也就是说在16ms内,View中要完成所有操作,这样人的视觉上就不会产生卡顿,如果要处理的操作太多,那么就会不断阻塞主线程,导致画面卡顿。在游戏里尤其明显,一般的FPS游戏,60桢和30桢区别就比较明显。所以,当你的自定义View需要频繁刷新,或者刷新时,数据处理量比较大时,推荐用SurfaceView,两者区别主要有三方面:
- View 适用于主动更新,SurfaceView适用于被动更新
- View在主线程中对画面进行刷新,SurfaceView通常通过一个子线程来进行页面的刷新。
- View 在绘图时没有使用双缓冲机制,SurfaceView在底层机制中就已经实现了双缓冲机制。
public class EraserView extends SurfaceView { private Paint paint; private Path path; private Bitmap bg,fg; private Canvas canva,canvas; private SurfaceHolder holder; public EraserView(Context context, AttributeSet attrs) { super(context, attrs); holder = getHolder(); paint = new Paint(); paint.setStyle(Paint.Style.STROKE); paint.setAlpha(0); paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN)); paint.setStrokeJoin(Paint.Join.ROUND); paint.setStrokeWidth(50); path = new Path(); bg = BitmapFactory.decodeResource(getResources(), R.drawable.bf); Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.bg); fg = Bitmap.createBitmap(bg.getWidth(),bg.getHeight(), Bitmap.Config.ARGB_8888); canva = new Canvas(fg); canva.drawBitmap(bitmap,0,0,null); } @Override public boolean onTouchEvent(MotionEvent event) { switch (event.getAction()){ case MotionEvent.ACTION_DOWN: path.reset(); path.moveTo(event.getX(),event.getY()); break; case MotionEvent.ACTION_MOVE: path.lineTo(event.getX(),event.getY()); break; } draw(); return true; } private void draw(){ try { canvas = holder.lockCanvas(); canvas.drawBitmap(bg,0,0,null); canva.drawPath(path, paint); canvas.drawBitmap(fg,0,0,null); }catch (Exception e){ e.printStackTrace(); }finally { if (null != canvas){ holder.unlockCanvasAndPost(canvas); } } }}
使用时,注意在绘制方法中,finally要加入unlockCanvasAndPost(canvas),来保证每次都能将内容提交。
0 0
- 自定义View 实现 刮刮卡效果和美女撕衣服
- 自定义View实现刮刮卡效果
- Android 自定义View 实现刮刮卡效果
- android 自定义view实现刮刮卡效果
- 和美女吃饭有感~~~~
- 金钱和美女
- 自定义view刮刮卡效果
- 自定义View实现SwichButton效果
- 自定义 View 实现钟表效果
- 自定义View实现索引效果
- 自定义view实现炸弹效果
- 安卓自定义view实现彩票刮刮卡效果
- Android自定义View-刮刮卡效果
- 自定义View实现转盘旋转效果
- 自定义view实现图文环绕的效果
- 自定义view实现水波荡漾的效果
- android自定义view实现progressbar的效果
- 自定义view实现水波纹效果
- MP Control 模块boost功能
- 封装AFNetWorking
- Nginx 安装与配置
- GBDT算法整理
- 从零开始搭建架构实施Android项目
- 自定义View 实现 刮刮卡效果和美女撕衣服
- java 中把double类型转成 int类型
- 计算机语言的数据范围
- SendMessage 死锁
- 手机网站开发趋势
- AlphaGo:黑色方碑?
- 二分答案法、三分法
- 选择C runtime 函数库
- sklearn线性回归学习中遇到的问题及解决方法