Cocos Creator 中 _worldMatrix 到底是什么(下) 1. 摘要
上篇介绍了矩阵的基本知识以及对应图形变换矩阵推倒。中篇具体介介绍了对应矩阵转换成cocos creator代码的过程。这篇我们将通过一个具体的实例来验证我们上篇和中篇的结果。
2. 场景准备新建一个cocos项目,在层级管理器Canvas下依次完成以下节点建立。
新建一个Sprite(单色)节点并设置大小为100,100黄色背景,取名matrixReference
新建一个Sprine(单色)节点并设置大小为100,100浅蓝色背景,取名matrix
在matrix节点下新建一个空节点,取名center。然后在属性检查器中添加Graphics组件,并设置Stroke Color 为蓝色
回到Canvas,新建一个空节点,取名line。然后在属性检查器中添加Graphisc组件,并设置Stroke Color为白色
脚本文件准备。在资源管理器scripts文件夹下,新建脚本 matrix.ts 和 line.ts。matrix.ts用来完成矩阵的验证操作。line.ts用来绘画一个平面的xy坐标系。
3. 绘制平面坐标系利用Graphic画笔功能,分别沿水平方向和垂直方向绘制长度100的两条直线。然后在轴的正方向绘制一个三角形箭头。绘制代码如下
start() { let g = this.getComponent(cc.Graphics); // y轴 g.moveTo(0, -100); g.lineTo(0, 100); g.lineTo(-10, 80); g.lineTo(10, 80); g.lineTo(0, 100); // x 轴 g.moveTo(-100, 0); g.lineTo(100, 0); g.lineTo(80, -10); g.lineTo(80, 10); g.lineTo(100, 0); g.stroke(); }将此用户组件分别绑定到节点line和center下,完成后刷新浏览器我们会看到如下界面
从上图可知,cocos creator 中层级覆盖方式是下覆盖上。所目前只能看浅蓝色的方块以及白色线条的坐标系。
4. 测试代码准备验证cocos creator 对应节点变换的矩阵信息,需要通过输出当前节点的本地矩阵和世界矩阵,以及当前节点设置信息,和父级节点的设置信息。所以我们在matrix.ts中先创建一个log函数用于输出当前节点各种属性状态值。代码如下:
log(title) { console.log(`---${title}---`); let wm = cc.mat4(); this.node.getWorldMatrix(wm); console.log("---1. [世界坐标矩阵]---"); console.log(wm.toString()); let lm = cc.mat4(); this.node.getLocalMatrix(lm); console.log("---2. [本地坐标矩阵]---"); console.log(lm.toString()); console.log("---3. [当前各属性状态]---"); console.log(` 1. position: ${this.node.position.toString()} 2. scale: ${this.node.scale.toString()} 3. angle: ${this.node.angle} 4. skewX: ${this.node.skewX} 5. skewY: ${this.node.skewY} 6. width: ${this.node.width} 7. height: ${this.node.height} 8. parentWidth: ${this.node.parent.width} 9. parentHeight: ${this.node.parent.height}`) console.log("---4. [锚点角(0,0)坐标信息]---") let wordVec = this.node.convertToWorldSpaceAR(cc.v2(0, 0)); let localVec = this.node.parent.convertToNodeSpaceAR(wordVec); console.log(`原点的世界坐标:${wordVec.toString()} 本地坐标: ${localVec.toString()}`); console.log("---5. [右上角(50,50)坐标信息]---") wordVec = this.node.convertToWorldSpaceAR(cc.v2(50, 50)); localVec = this.node.parent.convertToNodeSpaceAR(wordVec); console.log(`右上角的世界坐标:${wordVec.toString()} 本地坐标: ${localVec.toString()}`); }将matrix.ts以用户组件的方式添加到matrix节点。然后回到matrix.ts脚本当中,并在start方法中添加如下代码
start() { this.log("初始状态"); }编译运行,刷新浏览器,我们就可以在Console控制台中,看到如下信息
------------------初始状态------------------- ---1. [世界坐标矩阵]--- [ 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 480, 320, 0, 1 ] ---2. [本地坐标矩阵]--- [ 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1 ] ---3. [当前各属性状态]--- 1. position: (0.00, 0.00, 0.00) 2. scale: 1 3. angle: 0 4. skewX: 0 5. skewY: 0 6. width: 100 7. height: 100 8. parentWidth: 960 9. parentHeight: 640 ---4. [锚点角(0,0)坐标信息]--- 原点的世界坐标:(480.00, 320.00) 本地坐标: (0.00, 0.00) ---5. [右上角(50,50)坐标信息]--- 右上角的世界坐标:(530.00, 370.00) 本地坐标: (50.00, 50.00)从输出结果可知,当前节点的世界坐标,只有m12和m13有值分别是480和320。然后我们Canvas的宽高分别是960和460,锚点分别是0.5和0.5,此结果就已经说明了平移矩阵。当前节点本地坐标矩阵为单位矩阵,其他属性都保持默认值。这里有必要仔细看看输出的第4和第五。分别输出了当前节点原点位置和右上角的世界坐标和本地坐标。从世界坐标可知,右上角的坐标为原点实际坐标加上50(锚点0.5)480+50=530 。也符合预期。
5. 旋转30度在start中添加代码
start() { this.log("初始状态"); this.node.angle = 30; this.log("1. 旋转30°"); this.node.rotation=30; this.log("2. 旋转30°"); }