在CocosCreator引擎编辑中,节点的scale和size属性都可以改变节点内容的大小,如下图中可爱的椰子头,原图尺寸为512*512,在UI编辑时发现太大了,需要128*128的大小更适合。
scale&size此时将节点scale属性设置为0.25好,还是将size属性的高\宽设置128好?回忆一下你在做UI编辑时,习惯用那个属性控制节点大小,思考一下怎样做才是UI开发的最佳实践?
1. scale与size的区别
scale: 节点整体的缩放比例,影响所有子节点。可使用scaleX、scaleY控制节点X\Y轴的缩放。
size:节点内容尺寸,以像素为单位,修改size不影响子节点。size是一个对象,使用width\height控制宽\高像素尺寸。
通过上面属性说明,比较容易看出scale与size的区别有两点
- scale使用比例单位,size使用像素单位
- scale影响子节点,size不影响子节点
在API接口上,scale可以直接使用node.scale访问,但size却不行,需要过node.getContentSize()、node.setContentSize()这两个函数访问,不过size支持node.width、node.height属性访问控制宽\高。
2. 计算节点的实际像素尺寸
虽然scale/size两个属性都可以改变节点的大小,但是当这两个属性同时发生了变化 ,如何获取节点的实际像素大小呢?比如说,将上面截图中的椰子头节点scale X\Y改为0.5,size W/H改为256,它会变成下面这样:
scale&size同时修改你会发现,节点只有原来的1/16大小了,他的实际像素计算如下:
width = node.width * node.scaleX
height = node.height * node.scaleY
我们再进一步,如果它的父节点也被缩放了,那当前节点的实际像素尺寸又怎么计算呢?还好有引擎提供有API获取节点包围盒的大小,也就是节点实际看到的像素尺寸:
//节点在父节坐标系下的轴向对齐的包围盒
let rect1 = node.getBoundingBox();
getBoundingBox返回的是一个矩形cc.Rect对象的实例,其中的width\height就是节点的像素尺寸,x\y是矩形在父节点下的左下角位置。
有人可能会问,获取节点的实际尺寸有什么呢?最为常用情景就是做碰撞检测,简单的矩形碰撞并不会用到碰撞组件,而是使用cc.rectContainsPoint\cc.rectContainsRect这类函数做检测,例如:
- 触摸一个节点时,检查触摸点是否在节点区域中
- 检查将一个节点是否在另一个节点之区域内
检查一下你的项目代码,是否有直接使用getContentSize或width/height获取节点大小做类似上面的碰撞检测,尝试修改节点的scale属性看看是否还能正常工作。
修改scale属性节点的size并不会变化,由此也可以看出,使用scale修改节点外观大小不是一个好主意,简单的使用节点size获取节点大小也不是一个安全之举,你不能保证UI编辑人员不会同时改变scale属性。所以使用node.getBoundingBox()才是安全之道。
3. 图片尺寸变化对精灵节点的影响
在游戏开发中,时常会遇到图片资源更改的情况,比如:有一系列的角色图片,切图为512*512的尺寸,在游戏中只需要128*128或其它尺寸展示。
后来发现之前的切图过大,包体体积不理想,于是要求美术将其改为256*256的尺寸。这时做UI编辑的同学可能会被郁闷到,在UI编辑器中,他使用的是scale调整的精灵大小,那图片更新还得再全部重新调整,因为它会以图片原始尺寸的变化而按比列变化。
如果之前使用的是size属性控制的精灵尺寸,同时Script组件设置的sizeMode为CUSTOM,那图片的尺寸变化就不会影响精灵在游戏中的尺寸变化,所以size属性在这次胜出。
通过上面的举例,还有说明了一个问题,对游戏中的关键元素的尺寸规范预先规定下来非常的重要,也就是所谓的设计尺寸。设计尺寸不仅仅是屏幕设计尺寸用于规定背景图的大小,还包括统一的角色、图标、UI等等。
4. Sprite组件对图片大小的约束
上面提到了Sprite组件的sizeMode属性可以配合节点size对图片大小进行约束:
Sprite组件的SizeMode属性.jpg当sizeMode设置为CUSTOM时,不论图片尺寸是多大,当精灵帧spriteFrame变化时(可以尝试拖动不同尺寸的图片到spriteFrame属性上),都不会影响当前节点的size大小。如果你选择的是其它值,当spriteFrame变化时节点size也会随之变化。
scale则不然,scale会在size的基础上再做缩放,所以scale保持为1是最安全的,size属性又得1分。
5. 精灵的九宫模式
Sprite组件的type属性为SLICED时可开启精灵的九宫模式,当编辑好九宫属性后,用节点size属性可无限放大节点。
精灵九宫需要特别注意的是,九宫属性只适合将精灵节点放大,而不适合将节点缩小,如果九宫的边缘像素占比较大,缩小后会导致精灵变形。
因此使用九宫属性的图片尺寸尽量可能的要小,同时最好不要叠加scale属性,这会让精灵变形更为严重,size属性再得1分。
6. scale属性的应用
从上面得分来看scale属性好惨,保持为1是最安全的,根据Shawn的经验来看确实是这样,所以scale属性尽量少用(默认为1)。
说scale属性一无事处,确实也不太地道,scale属性至少有下面3个用处:
- 用于cc.ScaleTo/cc.ScaleBy的Action动画
- 用于有子节点的复杂界面的整体缩放,比如对一个预制件进行缩放
- 将scaleX或scaleY设置为负数,实现图片的左、右、上、下镜像减少资源量,比如下图中两个精灵这是同一张图片
所以scale属性的作就如同他的名字一样:缩放!不仅可以放大、缩小,还可以向负数缩放。
7. 小结
回到最初的问题,设置节点的大小使用size将是最佳的实践。这有助于在UI的编辑设计,只需要预先规划好界面元素的设计尺寸、文件名,无需太多考虑图片素材的尺寸,使用临时图片资源即可开始项目的开发。
当美术资源陆续更新到工程中时,可非常自信地对美术同学说,让暴风雨来的更猛烈些吧!
关注「奎特尔星球」微信公众号,我们一起成长。
网友评论