查看原文
其他

CocosCreator基础教程—聊聊scale与size属性(2)

张晓衡 Creator星球游戏开发社区 2021-08-09

在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的区别有两点

  1. scale使用比例单位,size使用像素单位

  2. 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这类函数做检测,例如:

  1. 触摸一个节点时,检查触摸点是否在节点区域中

  2. 检查将一个节点是否在另一个节点之区域内


检查一下你的项目代码,是否有直接使用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个用处:

  1. 用于cc.ScaleTo/cc.ScaleBy的Action动画

  2. 用于有子节点的复杂界面的整体缩放,比如对一个预制件进行缩放

  3. 将scaleX或scaleY设置为负数,实现图片的左、右、上、下镜像减少资源量,比如下图中两个精灵这是同一张图片


设置ScaleX为负数,实现向左镜像


所以scale属性的作用就如同他的名字一样:缩放!不仅可以放大、缩小,还可以向负数做缩放。

7. 小结

回到最初的问题,设置节点的大小使用size将是最佳的实践。这有助于在UI的编辑与设计,同时预先规划好游戏元素的设计尺寸、资源的文件名,无需太多考虑图片素材的尺寸,使用临时图片即可开始项目的开发。

当美术资源陆续更新到工程中时,我们可非常自信地对美术同学说,让暴风雨来的更猛烈些吧!


欢迎关注「奎特尔星球」微信公众号,一起成长!


    您可能也对以下帖子感兴趣

    文章有问题?点此查看未经处理的缓存