標籤:
在背景中用到了一個自訂的類 VectArr :
class VectArr{public:VectArr( const Bezier & bz, int conut = 30 ): _bezier( bz ), _count( conut ), _bottom( 0 ){_lines = new Vect[ _count + 2 ];getBezier( bz );}VectArr( int count = 30 ): _count( count ), _bottom( 0 ){_lines = new Vect[ count + 2];}VectArr( Vect * point ): _count( 2 ){_lines = new Vect[ _count + 2 ];_lines[ 0 ] = Vect( point->x, 0 );_lines[ 1 ] = Vect( point->x, Director::getInstance( )->getVisibleSize( ).height );}~VectArr( ){delete[ ]_lines;}private:Bezier _bezier;Vect * _lines;int _count;int _bottom;public:Bezier getBezier( ) const;Color4F getColor( ) const;void setColor(const Color4F & c );Vect * getLines( ) const;void setCountToBottom( int count );int getCountToBottom( );void setCount( int count );int getCount( ) const;VectArr * stiching( VectArr * other );};
類中儲存一個Bezier(自訂,在Data檔案夾下)變數 _bezier,一個Vect(cocos2d-x 中的二維向量,通常表示點)數組指標 _lines,一個整數 _count 對應的數組大小,一個整數 _bottom 附加點個數
兩點一直線,一個有N個點的數組可以看成是N-1條線段的數組,除了開頭和結尾的兩個點,其他點都與前後的連成兩條線段,為了方便,我把這個類的每個對象叫一條線,一條彎彎曲曲的線
這個類中還有幾個處理,線段的函數,比如計算線段交點的函數,上面沒給出,完整代碼點這裡查看。
回過頭來說下 Bezier 這個結構:
typedef struct Bezier{Vect begin;Vect end;Vect control1;Vect control2;Color4F color;Bezier( ) { }Bezier( Vect b, Vect e, Vect c1, Vect c2, Color4F c ): begin( b ), end( e ), control1( c1 ), control2( c2 ), color( c ){}~Bezier( ) { }void offset( const Vect & offset );}Bezier;
Bezier 有四個點和一個顏色(Color4F是cocos2d-x中儲存顏色的類,顏色的四個分量:r,g,b,a,數值在0?1之間)
這個結構體儲存一個貝賽爾曲線和對應的顏色,貝賽爾曲線由一個或兩個控制點,貝賽爾曲線可以畫出平滑的曲線,山體看起來更自然,也可以簡化資料存放區,不用儲存每一個點,只需要四個點就可以了,程式中在 VectArr 中轉化為繪圖所需的點數組:
Vect * VectArr::getBezier( const Vect & from, const Vect & to, const Vect & control1, const Vect & control2 ){float t = 0.0f;if( control2.isZero( ) ){for( unsigned int i = 0; i < _count; i++ ){_lines[ i ].x = powf( 1 - t, 2 ) * from.x + 2.0f * ( 1 - t ) * t * control1.x + t * t * to.x;_lines[ i ].y = powf( 1 - t, 2 ) * from.y + 2.0f * ( 1 - t ) * t * control1.y + t * t * to.y;t += 1.0f / _count;}_lines[ _count ].x = to.x;_lines[ _count ].y = to.y;}else{for( unsigned int i = 0; i < _count; i++ ){_lines[ i ].x = powf( 1 - t, 3 ) * from.x + 3.0f * powf( 1 - t, 2 ) * t * control1.x + 3.0f * ( 1 - t ) * t * t * control2.x + t * t * t * to.x;_lines[ i ].y = powf( 1 - t, 3 ) * from.y + 3.0f * powf( 1 - t, 2 ) * t * control1.y + 3.0f * ( 1 - t ) * t * t * control2.y + t * t * t * to.y;t += 1.0f / _count;}_lines[ _count ].x = to.x;_lines[ _count ].y = to.y;}_count += 1;return _lines;}
畫一座山需要多條線才有層次,用 LineLayer 儲存一座山的所有線段;而整個背景中有兩座山,用 BgLayerData 儲存這個兩座山的資料:
class LineLayer{public:LineLayer( );~LineLayer( );void AddBezier( float b1, float b2, float e1, float e2,float c11, float c12, float c21, float c22 );void AddBezier( float b1, float b2, float e1, float e2,float c11, float c12, float c21, float c22,float r, float g, float b, float a );std::vector<Bezier> getLines( ) const;bool isEmpty( )const;private:std::vector<Bezier> _lines;};class BgLayerData{public:BgLayerData( );~BgLayerData( );void AddLineLayer( LineLayer * l );std::vector<LineLayer*> * getLineLayer( ) const;private:std::vector<LineLayer*> * _lineLayer;};
這樣就把背景的資料儲存好,這畫背景時,用 VectArr 類的幾個方法處理下,就可以繪製背景了。
My Game --線段資料