您好,登錄后才能下訂單哦!
【嘮叨】
數學類Vec2、Size、Rect,是cocos2dx中比較常用的類。
比如設置圖片位置,設置圖片大小,兩圖片的碰撞檢測等等。
比起2.x版本,在3.x中本質上其實沒有太大的變化,主要的變化就是將全局宏定義相關的操作封裝到各自的類中而已。比如:Vec2的向量運算宏定義ccp***(),現在都已經封裝到Vec2類里面去了。
【番外】
在V2.x中,底層數學庫使用的是:Kazmath數學庫。
而在 V3.1 中,由于 Sprite3D 需要我們提供更多的API給開發者,這是Kazmath庫所不能提供的,而cocos2d-x內部擁有多個數學庫是沒有意義的。
所以V3.1中,底層選擇了新的數學庫:GamePlay3D數學庫。
【Vec2】
Vec2原名Point,它既可以表示一個二維坐標點,又可以表示一個二維向量。
同時Vec2對運算符進行了重載,可以很方便的完成Vec2的賦值、加減乘除等操作。另外還有與坐標向量相關的:距離、角度、點積、叉積、投影、標準化等操作。
此外在3.x中,還將2.x里的函數定義ccp***(如ccp,ccpAdd,ccpSub)相關的操作都封裝到了這個Vec2的類中,這樣就可以更加系統化地管理向量的運算操作了。
此外,除了Vec2。還有兩個坐標類:Vec3、Vec4,分別代表了三維、四維坐標向量。
查看2.x與3.x的變化請移步:http://shahdza.blog.51cto.com/2410787/1549850
Vec2可以是一個二維坐標點,也可以是一個二維向量。
1、創建方式
// /** * Vec2只有兩個成員變量x , y */ float x; //X坐標 float y; //Y坐標 /** * 構造函數 */ Vec2(); //(0 , 0) Vec2(float xx, float yy); //(xx , yy) Vec2(const float* array); //(array[0] , array[1]) Vec2(const Vec2& copy); //copy Vec2(const Vec2& p1, const Vec2& p2); //p2 - p1 //
2、設置向量坐標
使用set可以給向量重新設置新坐標值。
// void set(float xx, float yy); //(xx , yy) void set(const float* array); //(array[0] , array[1]) void set(const Vec2& v); //v void set(const Vec2& p1, const Vec2& p2); //p2 - p1 //
3、向量運算
其中包含了一些2.x中的ccp***()宏定義的函數,都全部封裝到了Vec2類中。
// /** * 向量運算 * void : 自身運算 , 值會改變 * 有返回值 : 返回運算結果, 值不會改變 */ void add(const Vec2& v); //相加( x+v.x , y+v.y ) void subtract(const Vec2& v); //相減( x-v.x , y-v.y ) void clamp(const Vec2& min, const Vec2& max); //將向量值限制在[min,max]區間內 void negate(); //向量取負( -x , -y ) void normalize(); //標準化向量. 若為零向量,忽略 void scale(float scalar); //x,y坐標同時放縮 void scale(const Vec2& scale); //x,y坐標分別放縮 void rotate(const Vec2& point, float angle); //繞point點, 旋轉angle弧度 float dot(const Vec2& v) const; //點積: x*v.x + y*v.y float cross(const Vec2& v) const; //叉積: x*v.y - y*v.x Vec2 project(const Vec2& v) const; //投影: 向量在v上的投影向量 float distance(const Vec2& v) const; //與v的距離. float distanceSquared(const Vec2& v) const; //與v的距離平方. float length() const; //向量長度. 即與原點的距離 float lengthSquared() const; //向量長度平方. 即與原點的距離平方 Vec2 getNormalized() const; //獲取向量的標準化形式. 若為零向量,返回(0,0) inline Vec2 getPerp() const; //逆時針旋轉90度. Vec2(-y, x); inline Vec2 getRPerp() const //順時針旋轉90度. Vec2(y, -x); inline float getAngle() const; //與X軸的夾角(弧度) float getAngle(const Vec2& v) const; //與v向量的夾角(弧度) inline Vec2 getMidpoint(const Vec2& v) const; //計算兩點間的中點 //將向量值限制在[min,max]區間內,返回該點 inline Vec2 getClampPoint(const Vec2& min, const Vec2& max) const { return Vec2(clampf(x, min.x, max.x), clampf(y, min.y, max.y)); } bool isZero() const; //是否為(0,0) bool isOne() const; //是否為(1,1) //判斷target是否在坐標點模糊偏差為var的范圍內. //if( (x - var <= target.x && target.x <= x + var) && // (y - var <= target.y && target.y <= y + var) ) // return true; bool fuzzyEquals(const Vec2& target, float variance) const; //以pivot為軸, 逆時針旋轉angle度(弧度) Vec2 rotateByAngle(const Vec2& pivot, float angle) const; //繞other向量旋轉 //返回向量: 角度 this.getAngle() +other.getAngle(); // 長度 this.getLength()*other.getLength(); inline Vec2 rotate(const Vec2& other) const { return Vec2(x*other.x - y*other.y, x*other.y + y*other.x); }; //繞other向量旋轉前的向量值 //返回向量: 角度 this.getAngle() -other.getAngle(); // 長度 this.getLength()*other.getLength(); //(這里是不是有點問題,難道不應該是this.getLength()/other.getLength()么?) inline Vec2 unrotate(const Vec2& other) const { return Vec2(x*other.x + y*other.y, y*other.x - x*other.y); }; //兩個點a和b之間的線性插值 //alpha ==0 ? a alpha ==1 ? b 否則為a和b之間的一個值 inline Vec2 lerp(const Vec2& other, float alpha) const { return *this * (1.f - alpha) + other * alpha; }; //平滑更新向量的當前位置,指向目標向量target. //responseTime定義了平滑時間量,該值越大結果越平滑,相應的延遲時間越長。 //如果希望向量緊跟target向量,提供一個相對elapsedTime小很多的responseTime值即可。 //參數 //target 目標值 //elapsedTime 消逝時間 //responseTime 響應時間 void smooth(const Vec2& target, float elapsedTime, float responseTime); /** * 自定義運算 * compOp */ //對該點向量形式的各分量進行function參數來指定的運算, //如absf,floorf,ceilf,roundf等, //任何函數擁有如下形式:float func(float)均可。 //例如:我們對x,y進行floor運算,則調用方法為p.compOp(floorf); //3.0 inline Vec2 compOp(std::function<float(float)> function) const { return Vec2(function(x), function(y)); } /** * 兼容代碼 * 估計是要被拋棄了~(>_<)~ */ void setPoint(float xx, float yy); //同set(float xx, float yy) bool equals(const Vec2& target) const; //同== float getLength() const; //同length() float getLengthSq() const; //同lengthSquared() float getDistance(const Vec2& other) const; //同distance(const Vec2& v) float getDistanceSq(const Vec2& other) const; //同distanceSquared(const Vec2& v) //
4、運算符重載
// inline const Vec2 operator+(const Vec2& v) const; //( x+v.x , y+v.y ) inline const Vec2 operator-(const Vec2& v) const; //( x-v.x , y-v.y ) inline const Vec2 operator*(float s) const; //( x*s , y*s ) inline const Vec2 operator/(float s) const; //( x/s , y/s ) inline const Vec2 operator-() const; //( -x , -y ) inline Vec2& operator+=(const Vec2& v); //(x,y) = ( x+v.x , y+v.y ) inline Vec2& operator-=(const Vec2& v); //(x,y) = ( x-v.x , y-v.y ) inline Vec2& operator*=(float s); //(x,y) = ( x*s , y*s ) inline bool operator<(const Vec2& v) const; inline bool operator==(const Vec2& v) const; inline bool operator!=(const Vec2& v) const; //
5、靜態函數與常量
// /** * 靜態方法 */ static void add(const Vec2& v1, const Vec2& v2, Vec2* dst); //dst = v1 + v2 static void subtract(const Vec2& v1, const Vec2& v2, Vec2* dst); //dst = v1 - v2 static void clamp(const Vec2& v, const Vec2& min, const Vec2& max, Vec2* dst); //將向量v限制在[min,max]區間內,結果存入dst static float angle(const Vec2& v1, const Vec2& v2); //兩向量夾角(弧度) static float dot(const Vec2& v1, const Vec2& v2); //兩向量點積 static inline Vec2 forAngle(const float a); //返回向量坐標 x=cos(a) , y=sin(a) /** * 靜態常量 */ static const Vec2 ZERO; //Vec2(0, 0) static const Vec2 ONE; //Vec2(1, 1) static const Vec2 UNIT_X; //Vec2(1, 0) static const Vec2 UNIT_Y; //Vec2(0, 1) static const Vec2 ANCHOR_MIDDLE; //Vec2(0.5, 0.5) static const Vec2 ANCHOR_BOTTOM_LEFT; //Vec2(0, 0) static const Vec2 ANCHOR_TOP_LEFT; //Vec2(0, 1) static const Vec2 ANCHOR_BOTTOM_RIGHT; //Vec2(1, 0) static const Vec2 ANCHOR_TOP_RIGHT; //Vec2(1, 1) static const Vec2 ANCHOR_MIDDLE_RIGHT; //Vec2(1, 0.5) static const Vec2 ANCHOR_MIDDLE_LEFT; //Vec2(0, 0.5) static const Vec2 ANCHOR_MIDDLE_TOP; //Vec2(0.5, 1) static const Vec2 ANCHOR_MIDDLE_BOTTOM; //Vec2(0.5, 0) //
6、線段相交檢測
這些用于檢測線段相交的函數,也都是靜態的成員函數。
// /** 線段相交檢測 v3.0 參數: A 為線段L1起點. L1 = (A - B) B 為L1終點 . L1 = (A - B) C 為線段L2起點. L2 = (C - D) D 為L2終點 . L2 = (C - D) S 為L1上計算各點的插值參數,計算方法為:p = A + S*(B - A) T 為L2上計算各點的插值參數,計算方法為:p = C + T*(D - C) */ //直線AB與線段CD是否平行 static bool isLineParallel(const Vec2& A, const Vec2& B, const Vec2& C, const Vec2& D); //直線AB與線段CD是否重疊 static bool isLineOverlap(const Vec2& A, const Vec2& B, const Vec2& C, const Vec2& D); //直線AB與直線CD是否相交 static bool isLineIntersect(const Vec2& A, const Vec2& B, const Vec2& C, const Vec2& D, float *S = nullptr, float *T = nullptr); //線段AB與線段CD是否重疊 static bool isSegmentOverlap(const Vec2& A, const Vec2& B, const Vec2& C, const Vec2& D, Vec2* S = nullptr, Vec2* E = nullptr); //線段AB與線段CD是否相交 static bool isSegmentIntersect(const Vec2& A, const Vec2& B, const Vec2& C, const Vec2& D); //返回直線AB與直線CD的交點 static Vec2 getIntersectPoint(const Vec2& A, const Vec2& B, const Vec2& C, const Vec2& D); //
【Size】
Size比較簡單,只是一個用來表示尺寸大小的類。寬為width,高為height。
和Vec2一樣,也對一些運算符進行了重載。
與2.x相比,沒有太大的變化。
PS: 因為和Vec2一樣,都只有兩個成員變量,所以Size和Vec2之間可以相互轉換。
1、主要函數如下
// class CC_DLL Size { /** * Size只有兩個成員變量width , height */ float width; //寬 float height; //高 /** * 構造函數 */ Size(); //(0, 0) Size(float width, float height); //(width, height) Size(const Size& other); //other explicit Size(const Vec2& point); //(顯式)構造函數. 構造時Size size = Size(Vec2&), 而不能Size size = vec2; /** * 相關操作 * - setSize * - equals * - Vec2() */ void setSize(float width, float height); //設置尺寸 bool equals(const Size& target) const; //判斷是否等于target //Size::Vec2() //返回類型為Vec2 operator Vec2() const { return Vec2(width, height); } /** * 靜態常量 */ static const Size ZERO; //(0, 0) /** * 運算符重載 */ Size& operator= (const Size& other); Size& operator= (const Vec2& point); //可以用Vec2賦值 Size operator+(const Size& right) const; Size operator-(const Size& right) const; Size operator*(float a) const; Size operator/(float a) const; }; //
【Rect】
Rect是一個矩形類。包含兩個成員屬性:起始坐標(左下角)Vec2、矩陣尺寸大小Size。
Rect只對“=”運算符進行了重載。
與2.x相比,多了一個函數unionWithRect,用于合并兩個矩形。
值得注意的是Rect類中:
intersectsRect函數,可以用作兩個Rect矩形是否相交,即碰撞檢測。
containsPoint 函數,可以用作判斷點Vec2是否在Rect矩形中。
unionWithRect 函數,可以用做將兩矩形進行合并操作。
1、主要函數如下
// class CC_DLL Rect { public: Vec2 origin; //起始坐標: 矩形左下角坐標 Size size; //尺寸大小 /** * 構造函數 */ Rect(); Rect(float x, float y, float width, float height); Rect(const Rect& other); /** * 運算符重載 * 只重載了 “=” 運算符 */ Rect& operator= (const Rect& other); /** * 相關操作 * - setRect * - getMinX , getMidX , getMaxX * - getMinY , getMidY , getMaxY * - equals , containsPoint , intersectsRect * - unionWithRect */ //設置矩形 void setRect(float x, float y, float width, float height); //獲取矩形信息 float getMinX() const; //origin.x float getMidX() const; //origin.x + size.width/2 float getMaxX() const; //origin.x + size.width float getMinY() const; //origin.y float getMidY() const; //origin.y + size.height/2 float getMaxY() const; //origin.y + size.height //判斷是否與rect相同. 原點相同,尺寸相同. bool equals(const Rect& rect) const; //判斷point是否包含在矩形內或四條邊上 bool containsPoint(const Vec2& point) const; //判斷矩形是否相交. 常常用作碰撞檢測. bool intersectsRect(const Rect& rect) const; //與rect矩形合并. 并返回結果. v3.0 //不會改變原矩形的值 Rect unionWithRect(const Rect & rect) const; /** * 靜態常量 * Rect::ZERO */ static const Rect ZERO; }; //
2、精靈創建中的一種方式
還記得Sprite的幾種創建方式嗎?里面有一種創建方式如下:
> Sprite::create(const std::string& filename, const Rect& rect)
若用Rect來作為創建Sprite精靈的參數,需要注意,從大圖中截取某一區域的圖片的Rect rect的構造應該是這樣的:
> Rect("小圖左上角坐標x", "小圖左上角坐標y", 小圖寬, 小圖高);
使用的是UIKit坐標系,而不是cocos2dx的OpenGL坐標系是不一樣的。
如下圖所示:
3、矩形合并函數unionWithRect
看幾張圖,你應該就會明白了。
兩個黑色矩形區域,使用unionWithRect合并后,變成紅色矩形區域。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。