第三篇:实践篇 《使用Assembler 实现图片任意切割功能》
实现原理:
共用一个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 实现图片任意切割功能》