價值百萬的技術(shù),又被社區(qū)開發(fā)者開源了(文末源碼)
支持合圖,支持
gizmo添加節(jié)點和調(diào)整位置,支持縮放旋轉(zhuǎn)。文章底部獲取完整項目!
效果預(yù)覽與使用
原理
回顧
在gizmo入門探索介紹了 gizmo 與多邊形裁剪的配合。
在使用 mesh 實現(xiàn)多邊形裁剪圖片 中介紹了 mesh 和切耳法的相關(guān)使用。

相比mask組件,這種meshRenderer的實現(xiàn)可以降低兩個draw call。
因為小伙伴使用的比較多,這邊對這個多邊形裁剪圖片進(jìn)行一次升級,增加易用性!
升級后添加了以下幾個特性:
升級版本至 Cocos Creator 2.4(一些接口的變化)支持 gizmo直接添加多邊形節(jié)點支持節(jié)點縮放旋轉(zhuǎn)后, gizmo的正確顯示支持合圖,圖片資源可以勾選 packable
接下來就大致講解主要特性的原理吧。
分割多邊形
這次不采用切耳法分割分割了,而是采用poly2tri這個庫去分割(注意這個庫有嚴(yán)格的限制)。
主要計算頂點索引過程如下。
//?計算頂點索引?
const?ids?=?[];
//?多邊形切割?poly2tri,支持簡單的多邊形,確保頂點按順序且不自交
const?countor?=?this.vertexes.map((p)?=>?{?return?{?x:?p.x,?y:?p.y?}?});?
const?swctx?=?new?poly2tri.SweepContext(countor,?{?cloneArrays:?true?});
swctx.triangulate();
const?triangles?=?swctx.getTriangles();
triangles.forEach((tri)?=>?{
????tri.getPoints().forEach(p?=>?{
????????const?i?=?countor.indexOf(p?as?any);
????????ids.push(i);
????});
})
mesh.setIndices(ids);
支持合圖
引用一張 @GT 的圖。

在 SpriteFrame 里含有這個uv信息,這里可以做一次轉(zhuǎn)換,先計算 0~1 的比例,再做一次轉(zhuǎn)化坐標(biāo)。
private?_lerp(a:?number,?b:?number,?w:?number)?{
????return?a?+?w?*?(b?-?a);
}
const?uv?=?this.spriteFrame.uv;
const?texture?=?this.spriteFrame.getTexture();
/**
*????t
*?l?????r
*????b
*/
const?uv_l?=?uv[0];
const?uv_r?=?uv[6];
const?uv_b?=?uv[3];
const?uv_t?=?uv[5];
//?計算uv
const?uvs?=?[];
for?(const?pt?of?this.vertexes)?{
????const?u?=?this._lerp(uv_l,?uv_r,?(pt.x?+?texture.width?/?2?+?this.offset.x)?/?texture.width);
????const?v?=?this._lerp(uv_b,?uv_t,?(pt.y?+?texture.height?/?2?-?this.offset.y)?/?texture.height);
????uvs.push(cc.v2(u,?v));
}
mesh.setVertices(gfx.ATTR_UV0,?uvs);
gizmo 增加多邊形頂點
整體思路是先根據(jù)所有頂點畫線段,給線段添加事件監(jiān)聽,在點擊位置添加一個節(jié)點。
點擊轉(zhuǎn)換坐標(biāo)有個坑,y的坐標(biāo)要用一個高度減去后再轉(zhuǎn)換(感謝@GT的pr)。
start:?(x,?y,?event,?param)?=>?{
????y?=?this._view.offsetHeight?-?y;
????//?坐標(biāo)轉(zhuǎn)換
????let?position?=?cc.v2(x,?y);
????position?=?Editor.GizmosUtils.snapPixelWihVec2(position);
????position?=?this._view.pixelToWorld(position);
????position?=?node.convertToNodeSpaceAR(position);
}
gizmo 支持旋轉(zhuǎn)縮放
整體來說,就是將坐標(biāo)點先做縮放,再做旋轉(zhuǎn)處理即可。
this._tool.plot(target.vertexes.map((p)?=>?{
????let?scaleX?=?node.scaleX;
????let?scaleY?=?node.scaleY;
????let?angle?=?-node.angle?*?Math.PI?/?180;
????const?cos_angle?=?Math.cos(angle);
????const?sin_angle?=?Math.sin(angle);
????const?v?=?Editor.GizmosUtils.snapPixelWihVec2(p.mul(this._view.scale));
????return?cc.v2(
????(v.x?*?cos_angle?*?scaleX?+?v.y?*?sin_angle?*?scaleY),
????-(-v.x?*?sin_angle?*?scaleX?+?v.y?*?cos_angle?*?scaleY)
????);
}),?position);
小結(jié)
坐標(biāo)轉(zhuǎn)換!旋轉(zhuǎn)!跳躍!不停歇!
以上為白玉無冰使用 Cocos Creator v2.4 實現(xiàn) "多邊形裁剪!" 的技術(shù)分享。如果對你有幫助,歡迎點贊(在看)讓我知道,這代表你對白玉無冰的認(rèn)可。
知識不過是潛在的力量,只有將它組織成明確的行動計劃,并指引它朝著某個明確目的發(fā)揮作用的時候,知識才是力量。
https://github.com/baiyuwubing/cocos-creator-examples
