CocosCreator基础教程—聊聊scale与size属性(2)
在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获取节点包围盒的大小,也就是节点实际看到的像素尺寸:
//节点在父节坐标系下的轴向对齐的包围盒
rect1 = node.getBoundingBox()
getBoundingBox返回的是一个矩形cc.Rect对象的实例,其中的width\height就是节点的像素尺寸,x\y是矩形在父节点下的左下角位置。
有人可能会问,获取节点的实际尺寸有什么呢?最为常用情景就是做碰撞检测,简单的矩形碰撞并不会用到碰撞组件,而是使用cc.rectContainsPoint\cc.rectContainsRect这类函数做检测,例如:
触摸一个节点时,检查触摸点是否在节点区域中
检查将一个节点是否在另一个节点之区域内
检查一下你的项目代码,是否有直接使用getContentSize()或width\height获取节点大小做类似上面的碰撞检测,尝试修改节点的scale属性看看是否还能正常工作。
修改scale属性,节点的size并不会变化。由此也可以看出,使用scale修改节点外观大小不是一个好主意;简单的使用getContentSize()获取节点大小也不是一个安全之举,你不能保证UI编辑的同学不会使用scale属性,所以使用node.getBoundingBox()才是安全之道。
3. 图片尺寸变化对精灵节点的影响
在游戏开发中,时常会遇到图片资源更改的情况,比如:有一系列的角色图片,切图为512*512的尺寸,但在游戏中只需要128*128或其它尺寸展示。
后来发现之前的切图过大,包体体积不理想,于是要求美术将其改为256*256的尺寸。这时做UI编辑的同学可能会被郁闷到,在UI编辑器中,他使用的是scale调整的精灵大小,那图片更新还得再全部重新调整,因为它会以图片原始尺寸的变化而按比列变化。
如果之前使用的是size属性控制的精灵尺寸,同时Script组件设置的sizeMode为CUSTOM(当修改精灵节点的size属性时Sprite组件的sizeMode会自动变为CUSTOM模块,默认为TRIMMED),那图片的尺寸变化就不会影响精灵在游戏中的尺寸变化,所以size属性在这次胜出。
通过上面的举例,还说明了一个问题,将游戏中的关键元素的尺寸预先规定下来非常的重要,这也就是在确定所说的设计尺寸。设计尺寸不仅仅只是屏幕设计尺寸用于规定背景图的大小,还包括统一的角色、图标、UI等等。
4. Sprite组件对图片大小的约束
上面提到了Sprite组件的sizeMode属性可以配合节点size对图片大小进行约束:
Sprite组件的SizeMode属性
当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属性好惨,根据Shawn这些年的经验来看将其保持为1是最安全的,所以scale属性尽量少用(默认为1)。
说scale属性一无事处,确实也不太地道,scale属性至少有下面3个用处:
用于cc.ScaleTo/cc.ScaleBy的Action动画
用于有子节点的复杂界面的整体缩放,比如对一个预制件进行缩放
将scaleX或scaleY设置为负数,实现图片的左、右、上、下镜像减少资源量,比如下图中两个精灵这是同一张图片
设置ScaleX为负数,实现向左镜像
所以scale属性的作用就如同他的名字一样:缩放!不仅可以放大、缩小,还可以向负数做缩放。
7. 小结
回到最初的问题,设置节点的大小使用size将是最佳的实践。这有助于在UI的编辑与设计,同时预先规划好游戏元素的设计尺寸、资源的文件名,无需太多考虑图片素材的尺寸,使用临时图片即可开始项目的开发。
当美术资源陆续更新到工程中时,我们可非常自信地对美术同学说,让暴风雨来的更猛烈些吧!
欢迎关注「奎特尔星球」微信公众号,一起成长!