实现原理:
共用一个texture、material、渲染状态等。紧通过修改vertex、uvs、indexes数据即可实现任意切割功能。
一、线段分割多边形,并分散多边形
-
线段分割多边形
已知多边形points,线段sp、ep。线段分割多边形得到两个多边形。
public splitPolygon(points: cc.Vec2[],sp: cc.Vec2,ep: cc.Vec2): cc.Vec2[][] {console.log(points);let intersectCount = 0;const polygon1 = [];const polygon2 = [];for (let i = 0; i < points.length; i++) {const p1 = points[i];const p2 = points[(i + 1) % points.length];this.convertToInt([p1, p2]);if (intersectCount === 0) {polygon1.push(p1);} else if (intersectCount === 1) {polygon2.push(p1);} else if (intersectCount === 2) {polygon1.push(p1);}const point = segmentIntersect(sp, ep, p1, p2);if (point !== null) {this.convertToInt([point]);polygon1.push(point);polygon2.push(point);intersectCount++;}}if (intersectCount === 2) {return [polygon1, polygon2];}return [polygon1];}
-
获得多边形数组创建成sprite
//分割多边形splitSprites(sprites: CustomSprite[]): void {for (let i = 0; i < sprites.length; i++) {console.log("第", i, "开始分割");const baseSprite = sprites[i];const points = baseSprite.getPolygon();const { sp, ep } = this.getLocalTouchEndPoint(baseSprite.node);const newPolygons = this.splitPolygon(points, sp, ep);newPolygons.forEach((polygon, i) => {if (i === 0) {baseSprite.setPolygon(polygon);} else {const node = new cc.Node();const sprite = node.addComponent(CustomSprite);sprite.texture2D = baseSprite.texture2D;node.parent = baseSprite.node.parent;node.position = baseSprite.node.position;sprite.setPolygon(polygon);this.customSprites.push(sprite);console.log("添加新的纹理");this.isDisperse = true;}});}}
-
以线段为边界和几何中心点位置,把多边形分散
//根据几何中心点拿到直线法向量分离disperseAllSprite(): void {if (!this.isDisperse) return;const { p1, p2 } = this.getGraphic();this.customSprites.forEach((sprite, i) => {const polygon = sprite.polygon;const centerP = calculatePolygonGeometryCenter(polygon);const wp = sprite.node.convertToWorldSpaceAR(centerP);const np = this.graphic.node.convertToNodeSpaceAR(wp);const pIntersect = pointLineNormal(np, p1, p2);const normal = pIntersect.normalize();sprite.node.x += normal.x * this.getDisperse();sprite.node.y += normal.y * this.getDisperse();sprite.setVertsDirty();// this.printPolygon(polygon);});}
二、Assembler自定义(vertex数据、uv数据、indexes数据)
第四篇:实践2 《使用MeshRender 实现图片任意切割功能》