Cocos Creator中坐標空間的轉換
在Cocos Creator游戲開發(fā)中,我們經常需要進行坐標空間的獲取、計算、判斷與轉換等操作。因此,掌握其中相關的基礎知識顯得非常重要。本文我們就一起來梳理回顧下。
一、?Vec2二維向量
?

? ? ?? ?let?v1?:?cc.Vec2?=?new?cc.Vec2(1,?0);
????????console.log(v1.equals(cc.Vec2.RIGHT));
????????let?v2?:?cc.Vec2?=?cc.v2(0,?1);
????????let?v3?:?cc.Vec2?=?v1.add(v2);
????????console.log("v3=",?v3,?v3.x,?v3.y);
????????console.log("v3的模,向量的長度:",?v3.mag());
????????//?v3歸一化,將向量的長度變成單位長度,游戲手柄
????????v3?=?v3.normalize();
????????console.log("歸一化后v3=",?v3,?v3.x,?v3.y);
????????console.log("單位向量v3的模,向量的長度:",?v3.mag());
?
????????//?*self方法改變調用這個方法的原有向量
????????console.log("調用*self方法前,v1=",?v1,?"v2=",?v2);
????????v3?=?v1.addSelf(v2);
????????console.log("調用后*self方法v1=",?v1,?"v2=",?v2);
常用方法案例如上,運行結果如下,其它方法類似,重點掌握向量的基本屬性、取模、比較相等、歸一化、加減乘除,區(qū)別帶self后綴的方法即可。

二、?cc.Size/cc.Rect尺寸和矩形
1: cc.Size: 包含寬度和高度信息的對象 {width: 100, height: 100};
2: new cc.Size(w, h), cc.size(w, h)創(chuàng)建一個大小對象;
3: cc.Rect: 矩形對象 new cc.Rect(x, y, w, h); cc.rect(x, y, w, h); {x, y, width, height}
4: ??contains(Point): 點是否在矩形內;
5: ? intersects : 兩個矩形是否相交;
6: ????intersection:計算兩個矩形的相交部分。
onLoad?()?{
????????let?s?:?cc.Size?=?new?cc.Size(100,?200);
????????console.log("s=",?s,?s.height,?s.width);
?
????????let?s2?=?cc.size(50,?60);
????????console.log("s2=",?s2,?s2.height,?s2.width);
????????console.log("s和s2尺寸是否相等:",?s.equals(s2));
????????console.log("s2的toString:",?s2.toString());
????}

start?()?{
????????let?r?:?cc.Rect?=?new?cc.Rect(0,?0,?100,?200);
????????console.log("r=",?r,?r.center,?r.origin,?r.size);
????????console.log("rx=",?r.x,?r.xMin,?r.xMax);
????????console.log("ry=",?r.y,?r.yMin,?r.yMax);
????????let?r2?:?cc.Rect?=?cc.rect(0,?0,?10,?20);
?
????????console.log("r和r2是否相交:",?r.intersects(r2));
????????let?r3?:?cc.Rect?=?new?cc.Rect();
????????r.intersection(r3,?r2);
????????console.log("r和r2的相交部分:",?r3);
?
????????let?p?:?cc.Vec2?=?new?cc.Vec2(50,?60);
????????console.log("p是否在矩形r中:",?r.contains(p));
????????console.log("p是否在矩形r2中:",?r2.contains(p));
????}

三、?Cocos Creator中的坐標系
1: 世界(屏幕)坐標系;
2: 相對(節(jié)點)坐標系,兩種相對節(jié)點原點的方式(1) 左下角為原點, (2) 錨點為原點(AR)
3: 節(jié)點坐標和屏幕坐標的相互轉換; 我們到底使用哪個?通常情況下帶AR;
4: 獲取在父親節(jié)點坐標系下(AR為原點)的節(jié)點包圍盒;
5: 獲取在世界坐標系下的節(jié)點包圍盒;
6: 觸摸事件對象世界坐標與節(jié)點坐標的轉換;
?onLoad?()?{
????????//?1?屏幕坐標系,左下角為原點,向右為x軸正方向,向上為y軸正方向
????????let?worldPos?:?cc.Vec2?=?new?cc.Vec2(0,?0);
????????console.log("worldPos=",?worldPos);
?
????????//?2:?相對(節(jié)點)坐標系,兩種相對節(jié)點原點的方式(1)?左下角為原點,?(2)?錨點為原點(AR)
????????let?localPos?:cc.Vec2?=?this.node.convertToNodeSpace(worldPos);
????????console.log("localPos節(jié)點左下角為坐標原點:",?localPos);
????????localPos?=?this.node.convertToNodeSpaceAR(worldPos);
????????console.log("localPosAR節(jié)點錨點為坐標原點",?localPos);
?
????????//?3:?節(jié)點坐標和屏幕坐標的相互轉換;?我們到底使用哪個?通常情況下帶AR;
????????localPos?=?cc.v2(0,?0);
????????worldPos?=?this.node.convertToWorldSpace(localPos);
????????console.log("世界坐標",?worldPos);
????????worldPos?=?this.node.convertToWorldSpaceAR(localPos);
????????console.log("世界坐標",?worldPos);
?
????????//?4:?獲取在父親節(jié)點坐標系下(AR為原點)的節(jié)點包圍盒;
????????let?box?:?cc.Rect?=?this.node.getBoundingBox();
????????console.log("父節(jié)點下的包圍盒子=",?box);
?
????????//?5:?獲取在世界坐標系下的節(jié)點包圍盒;
????????box?=?this.node.getBoundingBoxToWorld();
????????console.log("世界坐標下的包圍盒子=",?box);
????}




start?()?{
????????//?6:?觸摸事件對象世界坐標與節(jié)點坐標的轉換;
????????this.node.on(cc.Node.EventType.TOUCH_START,?function(e){
????????????let?worldPos?=?e.getLocation();
????????????let?localPos?=?this.node.convertToNodeSpaceAR(worldPos);
????????????console.log("觸摸點的世界坐標和本地坐標:",?worldPos,?localPos);
?
????????????localPos?=this.node.convertTouchToNodeSpace(e);
????????????console.log("觸摸點的本地坐標(節(jié)點左下角為坐標原點):",??localPos);
????????????localPos?=this.node.convertTouchToNodeSpaceAR(e);
????????????console.log("觸摸點的本地坐標(節(jié)點錨點為坐標原點):",??localPos);
????????}.bind(this),?this);
????}
運行結果如下,點擊藍色塊中間的位置。
?

關鍵點在于理解坐標參考原點在哪?