我们在玩“美女脱衣服”游戏中,看到的可以把美女身上的衣服脱掉,其实是运用了图层的技术。其根本还是两张图片,将上层图片来依据手的触摸使上层图层消失。可以理解为,上层图层是一个View,下层可以是View的一个背景。新建一个View类,myView

这样去写他的构造函数:

[java] view plaincopyprint?
  1. public myView(Context context) {
  2. super(context);
  3. setFocusable(true);
  4. setScreenWH();
  5. setBackgroundResource(R.drawable.back);
  6. Bitmap bmp = BitmapFactory.decodeResource(getResources(),R.drawable.background);
  7. setUpBmp(bmp);
  8. }

注释:

public void setFocusable (booleanfocusable)

Set whether this view can receivethe focus. Setting this to false will also ensure that this view is notfocusable in touch mode.

public void setBackgroundResource (intresid)

Set the background to a givenresource. The resource should refer to a Drawable object or 0 to remove thebackground.

setScreenWH();函数用来获得屏幕长宽像素。

public DisplayMetrics getDisplayMetrics ()

Return the current display metricsthat are in effect for this resource object. The returned object should betreated as read-only.

注意:Android可设置为随着窗口大小调整缩放比例,但即便如此,手机程序设计人员还是必须知道手机屏幕的边界,以避免缩放造成的布局变形问题。

手机的分辨率信息是手机的一项重要信息,很好的是,Android已经提供DisplayMetircs类可以很方便的获取分辨率。

Andorid.util包下的DisplayMetrics类提供了一种关于显示的通用信息,如显示大小,分辨率和字体。

为了获取DisplayMetrics成员,首先初始化一个对象如下:

DisplayMetrics myMetrics=new DisplayMetrics();

myMetrics =this.getResources().getDisplayMetrics();

//getWindowManager().getDefaultDisplay().getMetrics(myMetrics);

两种方式来给myMetrics值。

注:构造函数DisplayMetrics不需要传递任何参数;调用getWindowManager()之后,会取得现有Activity的Handle,此时,getDefaultDisplay()方法将取得的宽高维度存放于DisplayMetrics对象中,而取得的宽高维度是以像素为单位(Pixel),“像素”所指的是“绝对像素”而非“相对像素”。

setUpBmp(bmp);函数就是设置已经获取到的bmp为上层图像。

在setUpBmp(bmp);函数中,进行以下操作:

[java] view plaincopyprint?
  1. private void setUpBmp(Bitmap bmp) {
  2. // TODO Auto-generatedmethod stub
  3. myPaint = new Paint();
  4. myPaint.setAlpha(0);
  5. myPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN));
  6. myPaint.setAntiAlias(true);
  7. myPaint.setDither(true);
  8. myPaint.setStyle(Paint.Style.STROKE);
  9. myPaint.setStrokeCap(Paint.Cap.ROUND);
  10. myPaint.setStrokeJoin(Paint.Join.ROUND);
  11. myPaint.setStrokeWidth(20);
  12. // 设置路径
  13. myPath = new Path();
  14. myBitmap = Bitmap.createBitmap(SCREENW, SCREENH,Config.ARGB_8888);
  15. myCanvas = new Canvas();
  16. myCanvas.setBitmap(myBitmap);
  17. myCanvas.drawBitmap(bmp, 0, 0,null);
  18. }

注释:

public XfermodesetXfermode (Xfermodexfermode)

Set or clear the xfermode object.

Pass null to clear any previousxfermode. As a convenience, the parameter passed is also returned.

public PorterDuffXfermode (PorterDuff.Modemode)

Create an xfermode that uses thespecified porter-duff mode.

Xfermode有三个子类,分别如下:

AvoidXfermode 指定了一个颜色和容差,强制Paint避免在它上面绘图(或者只在它上面绘图)。

PixelXorXfermode 当覆盖已有的颜色时,应用一个简单的像素XOR操作。

PorterDuffXfermode 这是一个非常强大的转换模式,使用它,可以使用图像合成的16条Porter-Duff规则的任意一条来控制Paint如何与已有的Canvas图像进行交互。

要应用转换模式,可以使用setXferMode方法

对应的模式:

PorterDuff.Mode

ADD

Saturate(S + D)

PorterDuff.Mode

CLEAR

[0, 0]

PorterDuff.Mode

DARKEN

[Sa + Da - Sa*Da, Sc*(1 - Da) + Dc*(1 - Sa) + min(Sc, Dc)]

PorterDuff.Mode

DST

[Da, Dc]

PorterDuff.Mode

DST_ATOP

[Sa, Sa * Dc + Sc * (1 - Da)]

PorterDuff.Mode

DST_IN

[Sa * Da, Sa * Dc]

PorterDuff.Mode

DST_OUT

[Da * (1 - Sa), Dc * (1 - Sa)]

PorterDuff.Mode

DST_OVER

[Sa + (1 - Sa)*Da, Rc = Dc + (1 - Da)*Sc]

PorterDuff.Mode

LIGHTEN

[Sa + Da - Sa*Da, Sc*(1 - Da) + Dc*(1 - Sa) + max(Sc, Dc)]

PorterDuff.Mode

MULTIPLY

[Sa * Da, Sc * Dc]

PorterDuff.Mode

OVERLAY

PorterDuff.Mode

SCREEN

[Sa + Da - Sa * Da, Sc + Dc - Sc * Dc]

PorterDuff.Mode

SRC

[Sa, Sc]

PorterDuff.Mode

SRC_ATOP

[Da, Sc * Da + (1 - Sa) * Dc]

PorterDuff.Mode

SRC_IN

[Sa * Da, Sc * Da]

PorterDuff.Mode

SRC_OUT

[Sa * (1 - Da), Sc * (1 - Da)]

PorterDuff.Mode

SRC_OVER

[Sa + (1 - Sa)*Da, Rc = Sc + (1 - Sa)*Dc]

PorterDuff.Mode

XOR

[Sa + Da - 2 * Sa * Da, Sc * (1 - Da) + (1 - Sa) * Dc]

1.PorterDuff.Mode.CLEAR

所绘制不会提交到画布上。
2.PorterDuff.Mode.SRC

显示上层绘制图片
3.PorterDuff.Mode.DST

显示下层绘制图片
4.PorterDuff.Mode.SRC_OVER

正常绘制显示,上下层绘制叠盖。
5.PorterDuff.Mode.DST_OVER

上下层都显示。下层居上显示。
6.PorterDuff.Mode.SRC_IN

取两层绘制交集。显示上层。
7.PorterDuff.Mode.DST_IN

取两层绘制交集。显示下层。
8.PorterDuff.Mode.SRC_OUT

取上层绘制非交集部分。
9.PorterDuff.Mode.DST_OUT

取下层绘制非交集部分。
10.PorterDuff.Mode.SRC_ATOP

取下层非交集部分与上层交集部分
11.PorterDuff.Mode.DST_ATOP

取上层非交集部分与下层交集部分
12.PorterDuff.Mode.XOR

13.PorterDuff.Mode.DARKEN

14.PorterDuff.Mode.LIGHTEN

15.PorterDuff.Mode.MULTIPLY

16.PorterDuff.Mode.SCREEN

效果图:【成都安卓培训】

myPaint.setDither(true);

有时候你可能发现设置了背景图片之后,在屏幕上的效果不太理想,主要表现为颜色过渡不平滑,色块现象比较严重. 主要原因是因为WiEngine底层设置OpenGL的缓冲区格式缺省是RGB565,这个设置可以提高速度,但是很显然颜色精度会受到影响.这个时候可以用setDither(true)来解决, setDither是TextureNode的方法.

Sprite bg= ...;

bg.setDither(true);

Dither的意思是抖动,是一种用有限颜色模拟其它颜色的方式,比如将白色和红色均匀的混合,你会看到粉红色. 通过这种方式, 可以消除背景上的色块,使颜色过渡平滑. 这种方式当然会损失一点性能, 但是基本也就是背景用一下, 问题不大.

WYGLSurfaceView支持透明背景,这种模式下OpenGL使用RGBA8888格式的缓冲区,所以不需要抖动背景图片也将显示的很好.使用透明背景的WYGLSurfaceView很简单:

WYGLSurfaceViewv=new WYGLSurfaceView(this,true);//第二个参数传true表示背景透明

setContentView(v);

游戏需要用透明背景的不多,一般透明背景WYGLSurfaceView可以用在增强现实的应用中

myPaint.setStrokeCap(Paint.Cap.ROUND);

设置笔帽的样子。

myPaint.setStrokeJoin(Paint.Join.ROUND);

Paint.setStrokeJoin(Joinjoin)这里的Join参数为设置结合处的样子,Miter:结合处为锐角, Round:结合处为圆弧:BEVEL:结合处为直线。

OnDraw的实现:

[java] view plaincopyprint?
  1. protected void onDraw(Canvas canvas){
  2. canvas.drawBitmap(myBitmap, 0, 0,null);
  3. myCanvas.drawPath(myPath, myPaint);
  4. super.onDraw(canvas);
  5. }

运动轨迹算法:

[java] view plaincopyprint?
  1. private void touch_start(float x, float y){
  2. myPath.reset();
  3. myPath.moveTo(x, y);
  4. myX=x;
  5. myY=y;
  6. }
  7. private void touch_move(float x,float y){
  8. float dx = Math.abs(x-myX);
  9. float dy = Math.abs(y-myY);
  10. if(dx>=TOUCH_TOLERANCE || dy>=TOUCH_TOLERANCE ){
  11. myPath.quadTo(myX, myY, (x+myX)/2, (y+myY)/2);
  12. myX=x;
  13. myY=y;
  14. }
  15. }
  16. private void touch_up(){
  17. myPath.lineTo(myX, myY);
  18. myCanvas.drawPath(myPath,myPaint);
  19. myPath.reset();
  20. }

触摸重绘:

[java] view plaincopyprint?
  1. public boolean onTouchEvent(MotionEvent event){
  2. float x = event.getX();
  3. float y = event.getY();
  4. switch(event.getAction()){
  5. case MotionEvent.ACTION_DOWN:
  6. touch_start(x,y);
  7. invalidate();
  8. break;
  9. case MotionEvent.ACTION_MOVE:
  10. touch_move(x,y);
  11. invalidate();
  12. break;
  13. case MotionEvent.ACTION_UP:
  14. touch_up();
  15. invalidate();
  16. break;
  17. }
  18. return true;
  19. }

整个代码:

[java] view plaincopyprint?
  1. package com.blueeagle.www;
  2. import android.app.Activity;
  3. import android.content.Context;
  4. import android.graphics.Bitmap;
  5. import android.graphics.BitmapFactory;
  6. import android.graphics.Canvas;
  7. import android.graphics.Paint;
  8. import android.graphics.Path;
  9. import android.graphics.PorterDuff;
  10. import android.graphics.PorterDuffXfermode;
  11. import android.graphics.Bitmap.Config;
  12. import android.os.Bundle;
  13. import android.util.DisplayMetrics;
  14. import android.view.MotionEvent;
  15. import android.view.View;
  16. public class DuotucengActivity extends Activity {
  17. private int SCREENW;
  18. private int SCREENH;
  19. /** Calledwhen the activity is first created. */
  20. @Override
  21. public void onCreate(Bundle savedInstanceState) {
  22. super.onCreate(savedInstanceState);
  23. setContentView(new myView(this));
  24. }
  25. public class myView extends View {
  26. private Bitmap myBitmap;
  27. private Canvas myCanvas;
  28. private Paint myPaint;
  29. private Path myPath;
  30. private float myX,myY;
  31. private static final float TOUCH_TOLERANCE = 4;
  32. public myView(Context context) {
  33. super(context);
  34. setFocusable(true);
  35. setScreenWH();
  36. setBackgroundResource(R.drawable.back);
  37. Bitmap bmp = BitmapFactory.decodeResource(getResources(),R.drawable.background);
  38. setUpBmp(bmp);
  39. }
  40. private void setUpBmp(Bitmap bmp) {
  41. // TODO Auto-generatedmethod stub
  42. myPaint = new Paint();
  43. myPaint.setAlpha(0);
  44. myPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN));
  45. myPaint.setAntiAlias(true);
  46. myPaint.setDither(true);
  47. myPaint.setStyle(Paint.Style.STROKE);
  48. //myPaint.setStrokeCap(Paint.Cap.ROUND);
  49. myPaint.setStrokeJoin(Paint.Join.ROUND);
  50. myPaint.setStrokeWidth(20);
  51. // 设置路径
  52. myPath = new Path();
  53. myBitmap = Bitmap.createBitmap(SCREENW, SCREENH,Config.ARGB_8888);
  54. myCanvas = new Canvas();
  55. myCanvas.setBitmap(myBitmap);
  56. myCanvas.drawBitmap(bmp, 0, 0,null);
  57. }
  58. private void setScreenWH() {
  59. // TODO Auto-generatedmethod stub
  60. DisplayMetrics dm = new DisplayMetrics();
  61. //dm =this.getResources().getDisplayMetrics();
  62. getWindowManager().getDefaultDisplay().getMetrics(dm);
  63. int screenWidth = dm.widthPixels;
  64. int screenHeight = dm.heightPixels;
  65. SCREENW = screenWidth;
  66. SCREENH = screenHeight;
  67. }
  68. protected void onDraw(Canvas canvas){
  69. canvas.drawBitmap(myBitmap, 0, 0,null);
  70. myCanvas.drawPath(myPath, myPaint);
  71. super.onDraw(canvas);
  72. }
  73. private void touch_start(float x, float y){
  74. myPath.reset();
  75. myPath.moveTo(x, y);
  76. myX=x;
  77. myY=y;
  78. }
  79. private void touch_move(float x,float y){
  80. float dx = Math.abs(x-myX);
  81. float dy = Math.abs(y-myY);
  82. if(dx>=TOUCH_TOLERANCE || dy>=TOUCH_TOLERANCE ){
  83. myPath.quadTo(myX, myY, (x+myX)/2, (y+myY)/2);
  84. myX=x;
  85. myY=y;
  86. }
  87. }
  88. private void touch_up(){
  89. myPath.lineTo(myX, myY);
  90. myCanvas.drawPath(myPath,myPaint);
  91. myPath.reset();
  92. }
  93. public boolean onTouchEvent(MotionEvent event){
  94. float x = event.getX();
  95. float y = event.getY();
  96. switch(event.getAction()){
  97. case MotionEvent.ACTION_DOWN:
  98. touch_start(x,y);
  99. invalidate();
  100. break;
  101. case MotionEvent.ACTION_MOVE:
  102. touch_move(x,y);
  103. invalidate();
  104. break;
  105. case MotionEvent.ACTION_UP:
  106. touch_up();
  107. invalidate();
  108. break;
  109. }
  110. return true;
  111. }
  112. }
  113. }

Android开发之对上下两个图层的操作相关推荐

  1. android+动画+锯齿,Android_rotate--animation 动画旋转两图片,消除动画锯齿现象 android 开发:动画旋转两图片 - 下载 - 搜珍网...

    Android+动画旋转两图/ Android+动画旋转两图/.classpath Android+动画旋转两图/.project Android+动画旋转两图/.settings/ Android+ ...

  2. Android开发imageview实现上面两个圆角下面两个直角的效果

    效果图: 实现代码: RequestOptions options1 = new RequestOptions().centerCrop().placeholder(R.drawable.error) ...

  3. android 左滑按钮,android开发类似微信列表向左滑动按钮操作

    话不多说,直接上代码,有详细的注释的. layout布局中: 主要是跟大家说一下listview怎么写: android:id="@+id/pull_refresh_viewId" ...

  4. Android开发(22)--seekBar采用handler消息处理操作

    本案例简单实现进度条可走,可拖拽的功能,下面请看源码: 布局文件: <RelativeLayout xmlns:android="http://schemas.android.com/ ...

  5. Android事件的响应,Android 开发事件响应之基于监听的事件响应

    Android 开发事件响应之基于监听的事件响应 本文将介绍Android 操作系统如何通过监听来实现对事件的响应. Android 开发事件响应之基于监听的事件响应 背景介绍 Android 开发事 ...

  6. Android开发实践:线程与异步任务

    基于移动客户端的软件特别强调实时性,Android程序更是如此,任何一个程序超过5s没有响应,都会被系统强制杀掉.而且Android也不允许在UI线程中进行任何网络操作,否则就会产生NetworkOn ...

  7. 学习Android开发是否有前途?

    现在越来越多的手机.和平板电脑等产品都在采用安卓系统,Android开发的人才越来越缺乏,据统计,中国3G研发人才达到了3-400万.如果以后想从事安卓开发的工作,不仅仅要对程序技术非常熟练,还要了解 ...

  8. Android开发板串口(SerialPort)通信

    Android开发板串口(SerialPort)通信 Roy88关注 22017.09.07 18:01:22字数 1,618阅读 28,511 前言: 最近在总是看见有人在群里面问一些串口通信相关的 ...

  9. Android 开发的两种框架 MVC和MVP 的简单分析

    在常见的android开发框架,有MVC和MVP两种,下面我来分别简单介绍一下. 一.MVC框架 MVC,即model(模型),view(视图),controler(控制器)三个单词的简称. 其中Mo ...

  10. ubuntu12.04下android开发环境搭建两个注意事项

    2019独角兽企业重金招聘Python工程师标准>>> 这两天试着在ubuntu12.04上面搭建了一下android开发环境,其实搭建环境很简单,到国内更新很及时的镜像站http: ...

最新文章

  1. 这年头,做 Python 不懂点数据结构与算法真不行!
  2. CSDN博客越来越垃圾了,到处放广告
  3. cad线性标注命令_CAD图纸中怎么进行线性标注
  4. python 列表索引第一个字典_python开发(第三篇):python基本数据类型(列表,元组,字典)...
  5. 《JAVA课程设计》实训第四天——《猜猜看》游戏
  6. SQL查询语句执行速度快,存储过程执行慢
  7. [BUUCTF-pwn]——jarvisoj_level302-21
  8. 在线数理思维教育品牌“火花思维”完成4000万美元C轮融资
  9. Fiddler抓包工具 学习笔记
  10. 【Django 2021年最新版教程30】django项目部署到华为云(nginx uWSGI mysql方式)
  11. js递归遍历json对象,js循环遍历json数组
  12. 串口协议发送数据格式详细分析
  13. 中国工商银行科技岗面试
  14. 大数据,物联网和人工智能的关系
  15. c加加中print是什么意思_Java中的null到底是什么意思?
  16. 极光推送第一次进入APP无法获取RegistrationID
  17. Python画Sigmoid、Relu、Softmax、Tanh、Leaky relu等函数(1)
  18. Why Littlefinger says ‘an historic day‘ not ‘a historic day‘?
  19. Ubuntu22.04安装、配置、美化、软件安装、配置开发环境
  20. Qt Linguist 多语言支持

热门文章

  1. 2021-05-29 DOM元素的属性和操作:节点非内置属性,节点增删改查,cssDOM设置行内样式与非行内样式等
  2. 怎么用计算机打印出东西,怎样在电脑上打印东西_怎么用电脑打印东西
  3. 多节点什么网络取得技术性突破_我国学者研究“多节点量子网络”取得基础性突破...
  4. 从西天取经事件看官场潜规则
  5. Windows7 基本常见问题及解决方案之汇总
  6. 从零开始搭建ROS移动机器人系列之(四)直流电机PWM调速
  7. 使用scrapy爬取拉钩网招聘信息
  8. 积分墙、广告等违规应用如何在安卓市场上线
  9. JQuery 动态设置setInterval定时器时间间隔
  10. 读《虚幻引擎程序设计浅析》笔记