android自定义游戏闯关图,Android自定义View(四) -- Canvas

本文计划根据HenCoder系列文章进行学习,所以代码风格及博文素材可能会摘自其中。

1 范围裁切

范围裁切有两个方法: clipRect() 和 clipPath()。裁切方法之后的绘制代码,都会被限制在裁切范围内。

1.1 clipRect()

使用很简单,直接应用:

canvas.clipRect(100,100,400,400);

Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.snoopy);

canvas.drawBitmap(bitmap,100,100,paint);

bef2482c675d

原图 对比 裁切

记得要加上 Canvas.save() 和 Canvas.restore() 来及时恢复绘制范围。

1.2 clipPath()

其实和 clipRect() 用法完全一样,只是把参数换成了 Path ,所以能裁切的形状更多一些:

canvas.save();

path.addCircle(500,500,400, Path.Direction.CCW);

canvas.clipPath(path);

Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.snoopy);

canvas.drawBitmap(bitmap,100,100,paint);

canvas.restore();

bef2482c675d

image.png

2. 几何变换

几何变换的使用大概分为三类:

使用 Canvas 来做常见的二维变换;

使用 Matrix 来做常见和不常见的二维变换;

使用 Camera 来做三维变换。

2.1 使用 Canvas 来做常见的二维变换:

2.1.1 Canvas.translate(float dx, float dy) 平移

参数里的 dx 和 dy 表示横向和纵向的位移。

canvas.save();

canvas.translate(300,100);

canvas.drawBitmap(bitmap,100,100,paint);

canvas.restore();

bef2482c675d

image.png

2.1.2 Canvas.rotate(float degrees, float px, float py) 旋转

参数里的 degrees 是旋转角度,单位是度(也就是一周有 360° 的那个单位),方向是顺时针为正向; px 和 py 是轴心的位置。

canvas.save();

canvas.rotate(200);

canvas.drawBitmap(bitmap,100,100,paint);

canvas.restore();

bef2482c675d

2.1.3 Canvas.scale(float sx, float sy, float px, float py) 放缩

参数里的 sx sy 是横向和纵向的放缩倍数; px py 是放缩的轴心。

canvas.save();

canvas.scale(1.5f,0.8f,100,100);

canvas.drawBitmap(bitmap,100,100,paint);

canvas.restore();

bef2482c675d

2.1.4 skew(float sx, float sy) 错切

参数里的 sx 和 sy 是 x 方向和 y 方向的错切系数。

canvas.save();

canvas.skew(0.3f,0.3f);

canvas.drawBitmap(bitmap,100,100,paint);

canvas.restore();

bef2482c675d

2.2 使用 Matrix 来做变换

2.2.1 使用 Matrix 来做常见变换

Matrix 做常见变换的方式:

创建 Matrix 对象;

调用 Matrix 的 pre/postTranslate/Rotate/Scale/Skew() 方法来设置几何变换;

使用 Canvas.setMatrix(matrix) 或 Canvas.concat(matrix) 来把几何变换应用到 Canvas。

平移

matrix.reset();

matrix.postTranslate(300,300);

canvas.save();

canvas.concat(matrix);

canvas.drawBitmap(bitmap,100,100,paint);

canvas.restore();

bef2482c675d

.png

其他效果就不一一展示,和Canvas方法一样。

把 Matrix 应用到 Canvas 有两个方法: Canvas.setMatrix(matrix) 和 Canvas.concat(matrix)。

Canvas.setMatrix(matrix):用 Matrix 直接替换 Canvas 当前的变换矩阵,即抛弃 Canvas 当前的变换,改用 Matrix 的变换(注:根据下面评论里以及我在微信公众号中收到的反馈,不同的系统中 setMatrix(matrix) 的行为可能不一致,所以还是尽量用 concat(matrix) 吧);

Canvas.concat(matrix):用 Canvas 当前的变换矩阵和 Matrix 相乘,即基于 Canvas 当前的变换,叠加上 Matrix 中的变换。

2.2.2 使用 Matrix 来做自定义变换

Matrix 的自定义变换使用的是 setPolyToPoly() 方法。

2.2.2.1 Matrix.setPolyToPoly(float[] src, int srcIndex, float[] dst, int dstIndex, int pointCount) 用点对点映射的方式设置变换

private float[] pointSrc = {20,50,200,400, 80,90,300,50};

private float[] pointsDst = {10, 70, 320, 310, 200, 100, 310, 200};

matrix.reset();

matrix.setPolyToPoly(pointSrc , 0,pointsDst,0,3);

canvas.save();

canvas.concat(matrix);

canvas.drawBitmap(bitmap,100,100,paint);

canvas.restore();

bef2482c675d

image.png

参数里,src 和 dst 是源点集合目标点集;srcIndex 和 dstIndex 是第一个点的偏移;pointCount 是采集的点的个数(个数不能大于 4,因为大于 4 个点就无法计算变换了)。

2.3 使用 Camera 来做三维变换

Camera 的三维变换有三类:旋转、平移、移动相机。

2.3.1 Camera.rotate*() 三维旋转

Camera.rotate*() 一共有四个方法: rotateX(deg) rotateY(deg) rotateZ(deg) rotate(x, y, z)。这四个方法的区别不用我说了吧?

canvas.save();

camera.save();

camera.rotate(0,0,20);

camera.applyToCanvas(canvas);

camera.restore();

canvas.drawBitmap(bitmap,100,100,paint);

canvas.restore();

bef2482c675d

image.png

如果你需要图形左右对称,需要配合上 Canvas.translate(),在三维旋转之前把绘制内容的中心点移动到原点,即旋转的轴心,然后在三维旋转后再把投影移动回来:

canvas.save();

canvas.translate(100,100);

camera.save();

camera.rotate(-20,0,20);

camera.applyToCanvas(canvas);

camera.restore();

canvas.translate(-100,-100);

canvas.drawBitmap(bitmap,100,100,paint);

canvas.restore();

bef2482c675d

Canvas 的几何变换顺序是反的,所以要把移动到中心的代码写在下面,把从中心移动回来的代码写在上面。

2.3.2 Camera.translate(float x, float y, float z) 移动

它的使用方式和 Camera.rotate*() 相同,而且我在项目中没有用过它,所以就不贴代码和效果图了。

2.3.3 Camera.setLocation(x, y, z) 设置虚拟相机的位置

注意!这个方法有点奇葩,它的参数的单位不是像素,而是 inch,英寸。

bef2482c675d

image

我 TM 的真没逗你,我也没有胡说八道,它的单位就。是。英。寸。

这种设计源自 Android 底层的图像引擎 Skia 。在 Skia 中,Camera 的位置单位是英寸,英寸和像素的换算单位在 Skia 中被写死为了 72 像素,而 Android 中把这个换算单位照搬了过来。是的,它。写。死。了。

bef2482c675d

image

吐槽到此为止,俗话说看透不说透,还是好朋友。

在 Camera 中,相机的默认位置是 (0, 0, -8)(英寸)。8 x 72 = 576,所以它的默认位置是 (0, 0, -576)(像素)。

如果绘制的内容过大,当它翻转起来的时候,就有可能出现图像投影过大的「糊脸」效果。而且由于换算单位被写死成了 72 像素,而不是和设备 dpi 相关的,所以在像素越大的手机上,这种「糊脸」效果会越明显。

bef2482c675d

image

而使用 setLocation() 方法来把相机往后移动,就可以修复这种问题。

camera.setLocation(0, 0, newZ);

bef2482c675d

image

Camera.setLocation(x, y, z) 的 x 和 y 参数一般不会改变,直接填 0 就好。

好了,上面这些就是本期的内容:范围裁切和几何变换。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/244295.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

iPhone记步和Android计步,手机中运动步数是如何计算的?

微信运动每天都记录着你走路的步数,他会形成榜单,走的多收到很多赞,走的少则无人关注,如果你走到第一,你的照片将霸占排行榜封面。所以一段时间,每个人为了霸占封面疯狂走路、刷步,然而有时我们…

智能机器人建房子后房价走势_明后年日照房价走势如何?究竟是“上涨”还是下降...

想要在偌大的城市中拥有一个属于自己的家,那就必须要先有自己的一套房子,因为房子和自己以后的幸福生活密切相关。但是面对着如今格外高昂的房价,让很多人对房子产生了一种遥不可及的感觉。那么明后年日照房价走势如何呢?究竟是会…

dota迷你盒子Android5,DOTA:第一批TI7的迷你Aegis复制品已经到货

原标题:DOTA:第一批TI7的迷你Aegis复制品已经到货各地华丽的工艺。节日期间,一些Dota 2粉丝的完美礼物被封顶,他们本周开始收到令人垂涎的“宙斯盾”(Aegis of Champions)的缩影复制品。今年5月4日至10月1日举行的国际7战斗通行证…

鸿蒙系统下拉菜单,鸿蒙的js开发部模式17:鸿蒙的系统能力的应用模块

1. 鸿蒙的系统能力主要涉及通知消息模块,在模拟器中也可以实践和获取初始界面:点击发送通知,顶部出现通知消息的图标下拉通知菜单栏,出现通知信息:js的业务逻辑代码:import notification from system.notification;no…

华为 原生android 6.0,安卓6.0原生桌面轻体验,我的手机从未如此流畅过

本帖最后由 啷个里格弄 于 2016-12-30 13:05 编辑1.png (188.33 KB, 下载次数: 65)2016-4-29 18:21 上传▏写在开头P8的EMUI系统或者称之为桌面在功能性和流畅度上都给我留下不错的印象。但是成天盯着一款桌面难免“七年之痒”,楼主这边就来给大家的P8换换口味&…

兼容ios和android的ar,安卓又落后 这几款AR游戏只能iOS玩

近日苹果正式推送iOS 11,很多AR应用也随之上线。iOS 11一个很重要的亮点就是AR增强现实,利用它用户可以实现很多前所未有的体验,比如将室内的环境与游戏融为一体;还能测量距离。想知道你喜欢的明星身高吗?打开Measure这…

dilink智能网联系统鸿蒙系统,【图】秦Pro DM DiLink智能网联系统实测解读_汽车江湖...

一辆天天接触的车对于车主而言,早已不是一辆车这么简单了,更多时候它还充当我们的“好伙伴”甚至是“知己”,多少人下班停好车以后不愿意下车?因为他们知道这是一个分界点:推开车门你就是柴米油盐、是父亲、是儿子、是…

卓越性能代码_装好win10后,应该这样设置,才能压榨出系统十足的性能

用了这么久win10系统,你知道在win10中有不同的性能模式吗?而使用不同的性能模式会消耗不同的电量,就会为系统提供不同的性能。为了拥有好的性能,我们一般会在电源选项中给系统设置为高性能模式,但你以为这就够了吗&…

主管护士需要考计算机和英语吗,2020主管护师改为机考,一定要注意这些问题!...

原标题:2020主管护师改为机考,一定要注意这些问题!中国卫生人才网官方通知已确定,2020年护理学中级既主管护师考试形式-推行机考。那么,人机对话考试怎么考,有什么注意事项,为考生整理如下&…

html引用c 变量,在jsp页面中定义全局变量,供其他页面引用

一、在一个jsp中引用另一个jsp的方法有:1.使用 jsp include指令(常用):file属性是必填的(绝对或相对路径),但它不支持任何的表达式,也不允许通过?挂参方式来传递参数。注意:一般页面的top和bottom固定的时候…

html5 hgroup,HTML5 hgroup 标签

实例HTML5 使用 对标题进行组合:Welcome to my WWFFor a living planetThe rest of the content...尝试一下 浏览器支持IE 9、Firefox、Opera、Chrome 和 Safari 支持 标签。注释:IE 8 或更早版本的 IE 浏览器不支持 标签。标签定义及使用说明标签被用来…

html5 canvas实际应用,Html5 Canvas入门及经典应用

Html5 Canvas入门及经典应用时间:2019-02-15 来源:华清远见canvas想必对于前端的工程师都不陌生了,它是 HTML5 新增的「画布」元素,是HTML5 的一大亮点,canvas翻译过来其实就是画布的意思,它可以替代fl…

江恩 计算机,江恩理论基础篇

前言-废话我发这个贴的目的,不是教大家江恩理论,而仅仅是帮助探索者打通卡住的瓶颈,最重要的还是得靠自己。想想自己当初也是投师无门歪打乱撞进了MACD论坛江恩板块。所以还是得知恩图报。这几年没去工作,每天5-20小时全部砸在了江…

scrum回顾_3步开好回顾会 | IDCF FDCC认证学员作品

了解敏捷的人应该对回顾会不陌生,回顾会是在SCRUM框架五个活动中的最后一个活动,但是在敏捷的实际应用中,回顾会并不只是会在应用SCRUM的团队中使用,在其他敏捷实践中也会引入回顾会作为反馈环节。那么什么是回顾会呢?…

维沃丫3手机微信无法连接服务器1.104,手机微信网络连接不可用?教你4个方法,轻松解决网络问题!...

原标题:手机微信网络连接不可用?教你4个方法,轻松解决网络问题!微信,可以说是我们日常生活中离不开的一个通讯软件,无论是工作还是生活!而最近有位朋友使用手机微信的时候,明明网络信号十分好,…

金叉成功率_技巧!三分钟教会你识别macd真假金叉,让你精准把握买卖点!

如果看见MACD发生金叉就买,死叉就卖的话,或许早被市场消灭了。 机械的运用金叉/死叉信号来买卖还不如用投硬币来决定买卖会更省力些,而效果也不会差很多,只有在符合一定规则之下采用MACD发出的金叉/死叉信号,才可以大大提高信号的成功率。就像…

css规则可以放在云上,CSS中!important规则的使用方法

CSS中!important规则的使用方法发布时间:2020-06-15 10:53:11来源:亿速云阅读:129作者:Leah这期内容当中小编将会给大家带来有关CSS中!important规则的使用方法,以专业的角度为大家分析和叙述,阅读完这篇文…

ajax改变div内容,jquery ajax双击div可直接修改div中的内容

最近在做后台功能开发的时候,用到对排序字段的修改,感觉只为了修改一个排序值,而要重新进入编辑页比较麻烦,于是网上找点资料自己动手写了一个jquery双击实现直接修改排序值的效果:html代码:{$sort}JS代码&…

开榨油店的失败教训_想开水果店没有经验?线下开水果店经营心得分享,或许你用得上...

水果店随地都有,但能把水果店开好的人,似乎并不多见,那作为新人想开水果店,可以吸收哪些经验教训?想开店如何运作更好?且听小编细细道来。 很多开水果店的人都没有开好,那么有什么开水果店失败后…

js中的json ajax,js结合json实现ajax简单实例

这篇文章主要为大家详细介绍了js结合json实现ajax简单实例的相关资料,具有一定的参考价值,感兴趣的小伙伴们可以参考一下前期准备1、安装wampserver或者其他相似软件来搭建本地集成安装环境,我安装的是phpstudy2、html、js、css等文件需要放置…