1. 程式人生 > >cocos2dx-3.2(35) ClippingNode 遮罩

cocos2dx-3.2(35) ClippingNode 遮罩

我的生活,我的點點滴滴!!

可以根據一個模板切割圖片的節點--ClippingNode。這個類提供了一種不規則切割圖片的方式,在這種方式以前,我們可以使用紋理類

自帶的setTextureRect函式來切割矩形區域,而新特性中提供的ClippingNode最大的不同之處就是裁減將不僅僅侷限於矩形,可以根據

任何形狀進行裁減,而你要做的只是給一個“裁減模板”,首先來看這個類的常用函式(需要說明的是,這裡介紹的函式只是這個類獨

有的,這個類繼承自Node節點類,因此節點類有的函式也就不做介紹了)

下面來看看原始碼及其API:

/**
ClippingNode 是一個Node的子類,他使用"裁減模板"stencil(漏字模板,我喜歡這樣理解)

去遮擋他的內容(childs)。"裁減模板"stencil也是一個node結點,不會被draw。

怎麼產生效果了?裁剪是通過設定"裁減模板"stencil的alpha值來鏤空其中的一些區域。

作為節點,它就可以用作容器,承載其他節點和精靈。我把它叫底板。

如果想要對一個節點進行裁剪,那需要給出裁剪的部分,這個裁剪區域,我把它叫模版。

CCClipingNode裁剪節點在組成上=底板+模版,而在顯示上=底板-模版。

**/

class CC_DLL ClippingNode : public Node
{
public:
	//建立一個沒有stencil的裁剪node
    static ClippingNode* create();
    
	//建立一個帶有stencil的裁剪node,並且些stencil會被自動retain
    static ClippingNode* create(Node *stencil);

    /** The Node to use as a stencil to do the clipping.
     The stencil node will be retained.
     This default to nil.
     */
    Node* getStencil() const;
    void setStencil(Node *stencil);
    
	//底板內容被裁剪只有設定alpha的值小於stencil模板的值,那麼stencil區域就會裁剪掉,
	//所以如果我們設定clipper的alpha小於1,去裁剪底板。
    GLfloat getAlphaThreshold() const;
    void setAlphaThreshold(GLfloat alphaThreshold);
    
	/**
		這個用來設定顯示的部分:
		1、裁剪掉的部分
		2、剩餘的部分
		inverted預設是false,那就是顯示被裁剪掉的部分,如果設定成true,那就是顯示剩餘部分。
	**/
    bool isInverted() const;
    void setInverted(bool inverted);
	
};

我列出了部分我們極度需要的函式介面及其註釋。

簡單的描述一下,使用ClippingNode的流程:

1、建立”裁剪模板“stencil

2、建立裁剪結點ClippingNode(設定他兩的位置相同)

3、為裁剪結點ClippingNode設定stencil

4、設定裁剪結點ClippingNode中要放的內容(精靈)

上面的過程如果使用了setAlphaThreshold和setInverted這兩函式介面,就會產生不同的效果,這個按自己的需要自己去設定。上面的注

釋裡面也註明了設定這兩個引數後的效果cpp-test中的ClippingNodeTest例子講了大量的裁剪使用的方法及效果圖,後面文章有分析,這

裡實現一個類似於“濾鏡”顯示文字的ClippingNode例子。

例子1:使用精靈當stencil來裁剪LabelTTF

void HelloWorld::ClipFunc()
{
	Size s = Director::getInstance()->getWinSize();

	//建立裁剪node
	ClippingNode *clipper = ClippingNode::create();
	clipper->setAnchorPoint(Vec2(0.5,0.5));
	clipper->setPosition(Vec2(s.width * 0.5, s.height * 0.5));
	//不顯示底板
	//clipper->setInverted(true);
	//設定alpha值
	clipper->setAlphaThreshold(0.05);

	//建立一個四邊角形當content1
	DrawNode *sp = DrawNode::create();
	static Vec2 triangle[4];
	triangle[0] = Vec2(-120, -120);
	triangle[1] = Vec2(120, -120);
	triangle[2] = Vec2(120, 120);
	triangle[3] = Vec2(-120,120);
	Color4F mask(0,1,0,0.5);
	sp->drawPolygon(triangle, 4, mask, 0, Color4F(1,0,0,1));
	sp->setPosition(Vec2(50,50));
	//addChild
	clipper->addChild(sp);

	//在新增一段文字當content2
	LabelTTF *tf = LabelTTF::create("Testing long text", "Thonburi", 35);
	tf->setPosition(Vec2(50,50));
	//addChild
	clipper->addChild(tf);

	//用精靈當stencil
	Sprite *stencil = Sprite::create("bang.png");
	stencil->setPosition(Vec2(50,50));
	stencil->runAction(MoveBy::create(0.5, Vec2(60,0)));
	MoveBy *moveby = MoveBy::create(1, Vec2(-120,0));
	DelayTime *delay = DelayTime::create(0.5);
	stencil->runAction(delay);
	stencil->runAction(RepeatForever::create(Sequence::create(moveby, moveby->reverse(), NULL)));
	//設定模板
	clipper->setStencil(stencil);

	this->addChild(clipper);
}


效果圖:


例子2:使用DrawNode當stencil來裁剪精靈

void HelloWorld::ClipFunc()
{
	//自畫一個形狀來錄stencil
    DrawNode *stencil = DrawNode::create();
    static Point triangle[3];
    triangle[0] = Point(-100, -100);
    triangle[1] = Point(100, -100);
    triangle[2] = Point(0, 100);
    Color4F mask(0,1,0,1);
    stencil->drawPolygon(triangle, 3, mask, 2, Color4F(1,0,0,1));
    stencil->setPosition(Point(50,50));

    //裁剪node
    ClippingNode *clipper = ClippingNode::create();
    clipper->setAnchorPoint(Point(0.5,0.5));
    clipper->setPosition(Point(s.width * 0.5, s.height * 0.5));
    clipper->setAlphaThreshold(0.05);
    //clipper->setInverted(true);
    clipper->setStencil(stencil);
    this->addChild(clipper);

    //加普通物件進裁剪node,讓stencil去裁剪
    Sprite *sp = Sprite::create("bang.png");
    sp->setPosition(Point(50,50));
    sp->runAction(MoveBy::create(0.5, Point(60,0)));
    MoveBy *moveby = MoveBy::create(1, Point(-120,0));
    DelayTime *delay = DelayTime::create(0.5);
    sp->runAction(delay);
    sp->runAction(RepeatForever::create(Sequence::create(moveby, moveby->reverse(), NULL)));
    clipper->addChild(sp);

    //加普通物件進裁剪node,讓stencil去裁剪
    LabelTTF *tf = LabelTTF::create("Testing long text", "Thonburi", 35);
    tf->setPosition(Point(50,50));
    clipper->addChild(tf);
}

效果圖:


可以發現使用不同的stencil產生的效果決然不同,使用Shape(也就是自己DrawNode的形狀時),不要設定alpha的值,要不然就什麼也不顯示的。

有人留言說使用DrawNode當stencil時,形狀為圓形時,實際效果是正方形,原因估計是使用了DrawNode中的drawDot來畫的圓形吧?

DrawNode在3.x後不直接提供畫空心圓的介面了,那麼我們想要一個空心圓怎麼辦,可以使用多邊形逼近,但是鋸齒很明顯,沒研究怎麼去消除。

下面是使用空心圓作stencil來ClippingNode的效果圖,一切正常:

/*使用DrawNode畫圓當stencil*/
void HelloWorld::ClipFunc()
{
	auto s = Director::getInstance()->getWinSize();

	//自畫一個形狀來錄stencil
	DrawNode *stencil = DrawNode::create();
	stencil->setAnchorPoint(Point(0.5,0.5));
	//多邊形定點個數;
	Vec2 points[720];
	//圓心,相對座標;
	Vec2 center(0,0);
	//半徑;
	float R = 30;
	/**普及下求圓座標的方法
	* 已經半徑r、圓心座標(cX,cY)、圓心偏移角度a,求出其相應偏移角度的座標(X1,Y1);
	* X1 = cX + cos(a*3.14/180)*r;
	* Y1 = cY + sin(a*3.14/180)*r;
	*/
	// 畫空心圓->使用多邊形畫,分成720等分;
	// 鋸齒蠻明顯,不知道怎麼消除鋸齒;
	for( int i=0; i < 720; i++)
	{
		float x = center.x + cos(0.5*i*3.14/180) * R;
		float y = center.y + sin(0.5*i*3.14/180) * R;
		points[i] = Vec2(x,y);
		log("%f,%f", x, y);
	}
	//畫多邊形;
	stencil->drawPolygon(points, sizeof(points)/sizeof(points[0]), Color4F(0,1,0,0), 1, Color4F(1,0,0,1));
	stencil->setPosition(Point(50,50));

	//裁剪node
	ClippingNode *clipper = ClippingNode::create();
	clipper->setAnchorPoint(Point(0.5,0.5));
	clipper->setPosition(Point(s.width * 0.5, s.height * 0.5));
	//clipper->setAlphaThreshold(0.05);
	//clipper->setInverted(true);
	clipper->setStencil(stencil);
	this->addChild(clipper);

	//加普通物件進裁剪node,讓stencil去裁剪
	Sprite *sp = Sprite::create("grossini.png");
	//sp->setScale(4);
	sp->setPosition(Point(50,50));
	sp->runAction(MoveBy::create(0.5, Point(60,0)));
	MoveBy *moveby = MoveBy::create(1, Point(-120,0));
	DelayTime *delay = DelayTime::create(0.5);
	sp->runAction(delay);
	sp->runAction(RepeatForever::create(Sequence::create(moveby, moveby->reverse(), NULL)));
	clipper->addChild(sp);

	//加普通物件進裁剪node,讓stencil去裁剪
	/*LabelTTF *tf = LabelTTF::create("Testing long text", "Thonburi", 35);
	tf->setPosition(Point(50,50));
	clipper->addChild(tf);*/
}

效果圖:


相關推薦

cocos2dx-3.2(35) ClippingNode

我的生活,我的點點滴滴!! 可以根據一個模板切割圖片的節點--ClippingNode。這個類提供了一種不規則切割圖片的方式,在這種方式以前,我們可以使用紋理類 自帶的setTextureRect函式來切割矩形區域,而新特性中提供的ClippingNode最大的不同之處就

cocos2dx 3.x 蒙板 點選圓功能

//註冊觸控 EventListenerTouchOneByOne *listener = EventListenerTouchOneByOne::create(); listener->onTouchBegan = CC_CALLBACK_2(Hell

cocos2dx 3.2 裁剪節點 ClippingNode

// //[1].背景圖片(Layer層中) Sprite* bg = Sprite::create("HelloWorld.png"); bg->setPosition(visibleSize / 2); this->addChild(bg); //[2].建立

cocos2dx[3.2](1) 淺析cocos2dx3.2引擎目錄

    3.x的引擎目錄與2.x的引擎目錄的差別是非常大的。3.x主要是將引擎的各個檔案按照用途進行了分類,使得引擎目錄結構更加清晰了。     從目錄中我們主要了解一下以下幾個檔案: 檔名 說明 build 官方編譯的專案解決方案。

cocos2dx[3.2](15)——顏色混合BlendFunc

原文:點此 1、概念     “混合”是指兩種顏色的疊加方式。在新圖片將要渲染畫到螢幕上的時候,將用在新圖片中的紅、綠、藍和透明度資訊,與螢幕上已經存在的圖片顏色資訊相融合。     說的具體一點,就是把某一畫素位置上原來的顏色和將要畫上去的顏色,通過某種方式混在

cocos2dx[3.2]小知識——Sprite轉換為Image

RenderTexture* pRender = RenderTexture::create(pNewSpr->getContentSize().width, pNewSpr->getContentSize().height, Texture2D::PixelFormat::RGBA8888);

cocos2dx 3.2 中Sequence和Spawn無法執行RepeatForever動作的問題解決

   (博主qq,1204802552,歡迎交流)  有時候,我們想在Sequence或者Spawn中加入RepeatForever的動作,但在實際執行中,該迴圈動作並未得到執行,我們先來說下解決的方法。    對於Spawn,很簡單,我們只需要把RepeatForever

cocos2dx 3.2版本window環境安裝 vs2013編譯

      系統版本win8.1,關於系統的問題,win8,win7下的可選擇直接升級win8.1,前提是所用的win8,win7版本必須是啟用的,若是未啟用的系統可能會出現升級不成功的情況,因為未啟用的版本不能獲得微軟的部分更新服務資訊。至於具體的 升級方法可參見網上很多

【quick-cocos2d-x 遊戲開發】quick cocos2dx 3.2最穩定版 建立工程+sublime除錯執行

測試環境mac quick cocos2dx 3.2 quick cocos2dx 3.2版本已經差不多了 已經可以建立工程使用了,看下流程 1.最新版quick cocos2dx 3.2 建立工程,編譯,執行 1.1下載 按照README配置工程,執行player3

cocos2dx 3.2 學習篇之六(精靈運動,自定義運動軌跡(太極八卦))

        好了,今天想要講的是如何讓精靈按照自己定義的路徑去運動,官方給我們了一個action類,裡面有很多運動的型別,比如bezier曲線運動,比如jump運動等等,設計好了運動之後,我們只要讓精靈調運runAction()即可。 本人呢是十足的秦時明月粉絲,特別喜

cocos2dx[3.2](8)——新回撥函式std::bind

【嘮叨】 自從3.0引用了C++11標準後,回撥函式採用的新的函式介面卡:std::function、std::bind。 而曾經的回撥函式menu_selector、callfunc_selector、cccontrol_selector等都已經被無情的拋棄

cocos2dx 3.2】Flappy Bird開發超詳細講解(六)主角小鳥的建立

本文可以隨意轉載,轉載請註明出處,謝謝! 像之前我們說的,GameLayer是管家,其他的東西(小鳥,管道,草地等)各自封裝成類。現在我們就把主角小鳥封裝成一個類。 在這裡我們先思考下,我們有三種不同顏色的小鳥,在預載入LoadingScene裡我們給它們初始化了各自的動

cocos2dx[3.2]——新字型標籤Label

【嘮叨】     在3.x中,廢棄了2.x裡的LabelTTF、LabelAtlas、LabelBMFont三個字型類,取而代之的是全新的字型標籤Label。     實際上Label是將三個字型類進行了融合,進行統一的管理與渲染,這使得建立字型標籤Lab

cocos2dx.3.2 physics

/** 建立一個body mass和moment為預設值 */ static PhysicsBody* create(); /** 建立一個質量為mass的body moment為預設值. */ static PhysicsBody* create(f

cocos2dx 3.x 給Sprite新增

引言 程式截圖:   有時候,你在做遊戲時,可能需要一種方式來顯示精靈的某一部分(就是新增遮罩啦)。   一種方式就是使用另外一張圖片,叫做mask。你把mask圖片中間設定成白色,白色區域是被mask圖片的可見區域。之後這個白色區域會透明的。   然後,你可

介面操作結果提示彈出框2--層效果

js包含了html程式碼和顯示消失的功能,忽然想起來link可以去掉css的,因為在其他html介面裡會呼叫這些css樣式 suernk.js如下: //brace.html裡的三個彈出框,為了避免呼叫麻煩,將彈出框放到js裡 //document.write("<link rel='

前端小記2層)

瀏覽網頁時點選登入彈出登入框後,之前的網頁會被虛化,這是遮罩層在發揮作用。 實現方式如下(重點配置遮罩層): 1.在網頁html中加上一個遮罩層的div,如:<div class="overCurtain"> </div>和登入框 2.設定遮罩層css: .overC

學習筆記3--CSS製作滑鼠放上後淡入透明層效果

transition: Internet Explorer 10、Firefox、Opera 和 Chrome 支援 transition 屬性。 Safari 支援替代的 -webkit

iperf-2.0.5移植到IMX6DQRM的linux-3.0.35

首先匯出交叉編譯鏈的路徑: export PATH=$PATH:/opt/freescale/usr/local/gcc-4.6.2-glibc-2.13-linaro-multilib-2011.12/fsl-linaro-toolchain/bin/ 切換到iperf-2.0.5的主目錄

cocos2dx 利用層來實現地圖的簡單尋路

談到地圖不少人都說要做地圖編輯器了,但是我暫時繞過這一步,如果不用尋路地圖就不能移動?尋路就是會繞過障礙物的演算法。 我做了一個簡單的地圖的思想,就是地圖分層3層:背景層、可行區域層、遮罩層,但是地圖就不尋路了,通過設定可行區域層來 實現地圖障礙物的方法。下面看一個檢視,