Reduce polygon calculations! Draw cake of ~

Results the preview

review

Chain of holes in physics! To achieve! The PolyBool and chain component (cc.PhysicschainCollider) are introduced in this tutorial.

Although this scheme may not be the best scheme, but there is an evenodd thought, feel good.

Chain of holes in physics! Optimization! Several optimizations are described in the video.

Among them, the idea of unit and the idea of smooth movement have been used in the subsequent.

The polygonal chain component, however, has a problem of being easy to penetrate.

Then, after many times of search and analysis, in the physical hole of the polygon! To achieve! Described in the polygon collision component (cc. PhysicsPolygonCollider) to achieve physical digging holes.

The idea is to use Clipper to compute polygons (more efficient than PolyBool), then use Poly2tri to split polygons into triangles and fill them with rigid polygons.

However, poly2tri is more limited to physically burrowed polygons! Filling holes! The road of pit filling is introduced.

And use the graphics of mask to achieve beautiful texture.

Of course, there is also the 3D effect that the group members discussed and shared. On the basis of the above, we modified a 3D effect of physical digging hole. Thank you for your sharing!

It is strongly recommended to read the above articles in order to better understand this article!

Realize the principle of

The whole idea is to divide regions into blocks. When you click, you can determine which region blocks have operation, and then perform polygon calculation on these region blocks, and finally draw all polygons.

Here are polygons with physical digging holes! To achieve! The difference in poly2tri is that there is one less step. How is this done?

First of all, the reason we used poly2tri was because we had inner polygons.

Therefore, when dividing the blocks, as long as the size of the blocks is smaller than the size of the holes, there will be no inner polygons.

How do you tell which area you’re clicking on?

At initialization, a 2D rectangle (cc.rect) array is used to record the information for each block.

private _rects: cc.Rect[] = [];
Copy the code

A polygon is generated when clicked (see the chain of physical burrowing! Optimization! Touch smooth continuous) data in.

For each point of the polygon, calculate the maximum and minimum values of the coordinates x and y.

This can then be calculated as a polygon rectangle (AABB (axis-aligned Bounding Box)).

let xMin = Number.MAX_SAFE_INTEGER, xMax = Number.MIN_SAFE_INTEGER, yMin = Number.MAX_SAFE_INTEGER, yMax = Number.MIN_SAFE_INTEGER;
// Calculate the minimum maximum value
xMin = p.x < xMin ? p.x : xMin;
yMin = p.y < yMin ? p.y : yMin;
xMax = p.x > xMax ? p.x : xMax;
yMax = p.y > yMax ? p.y : yMax;
// Get the rectangle
const rect_r = cc.Rect.fromMinMax(cc.v2(xMin, yMin), cc.v2(xMax, yMax));
Copy the code

Then use this rectangle and the initialization rectangle to make an intersection judgment, so that we can roughly determine the block to calculate.

for (let index = 0; index < this._rects.length; index++) {
    const rect = this._rects[index];
    if (rect.intersects(rect_r)) {
        this.polyEx.pushCommand('polyDifference', [regions, index])
    }
}
Copy the code

Polygon calculation is Clipper, using the interface can refer to the official website or physical digging polygon! .

// polyDifference(poly: cc.Vec2[], index: number) {
// Compute the new polygon
// https://sourceforge.net/p/jsclipper/wiki/documentation
const cpr = new ClipperLib.Clipper(ClipperLib.Clipper.ioStrictlySimple);
const subj_paths = this._polys[index];
const clip_paths = [this._convertVecArrayToClipperPath(poly)]
cpr.AddPaths(subj_paths, ClipperLib.PolyType.ptSubject, true);
cpr.AddPaths(clip_paths, ClipperLib.PolyType.ptClip, true);
const subject_fillType = ClipperLib.PolyFillType.pftEvenOdd;
const clip_fillType = ClipperLib.PolyFillType.pftEvenOdd;
const solution = new ClipperLib.Paths();
cpr.Execute(ClipperLib.ClipType.ctDifference, solution, subject_fillType, clip_fillType);
this._polys[index] = solution || [];
Copy the code

After all the block calculation, finally draw the polygon collision body and texture as a whole.

// private draw() {
ctx.clear();
for (let index = 0; index < this._polys.length; index++) {
    const polygons = this._polys[index];
    for (let index2 = 0; index2 < polygons.length; index2++) {
        const polygon = polygons[index2];
        let c = this._physicsPolygonColliders[_physicsPolygonColliders_count];
        c.points = this._convertClipperPathToVecArray(polygon);
        c.apply();

        for (let index3 = 0; index3 < c.points.length; index3++) {
            const p = c.points[index3];
            if (index3 === 0) ctx.moveTo(p.x, p.y);
            else ctx.lineTo(p.x, p.y);
        }
        ctx.close();
    }
}
ctx.fill();
Copy the code

Of course, the group (859642112) in my friend @Wu also realized this block, block calculation of polygons at the same time, but also block drawing, welcome to add group discussion!

summary

Where there is life, there is digging!

Above is white jade without ice using Cocos Creator V2.3.3 to develop “Physical digging blocks!” Technology sharing. If it helps you, please share it with your friends.

Are things difficult or easy in the world? For it, the sufferers are easy; If you do not, it is difficult to make things easy. Is it difficult for people to learn? Learn, then the sufferers are easy; Do not learn, then easy is difficult. — For Learning


Original link to complete code (see Readme) Original article navigation