# 实现步骤

## 引入 `PolyBool`

`PolyBool`是什么？对多边形（并集，交集，差，异或）进行运算。(Boolean operations on polygons (union, intersection, difference, xor).)

```private _regions: number[][][] = [];
reset() {
this._regions = [
[[-480, -320], [-480, 250], [480, 250], [480, -320]]
];
}
```

## 添加物理链条

```//onLoad() {
cc.director.getPhysicsManager().enabled = true;
cc.director.getPhysicsManager().debugDrawFlags = 1;
for (let index = 0; index < 100; index++) {
const c = this.node_dirty.addComponent(cc.PhysicsChainCollider);
c.loop = true;
c.enabled = false;
}
```

```// draw() {
const chains = this.node_dirty.getComponents(cc.PhysicsChainCollider);
chains.forEach((c) => {
c.enabled = false;
})
for (let index = 0; index < this._regions.length; index++) {
const pos = this._regions[index];
let poly = chains[index];
if (!poly) {
poly.loop = true;
}
poly.points.length = 0;
poly.points = pos.map((v, i) => {
const v2 = cc.v2(v[0], v[1])
return v2;
});
poly.enabled = true;
}
```

## 开始挖洞！

```// onLoad() {
this.node_dirty.on(cc.Node.EventType.TOUCH_START, this._touchMove, this);
this.node_dirty.on(cc.Node.EventType.TOUCH_MOVE, this._touchMove, this);
```

```// const DIG_RADIUS = 50;
// const DIG_FRAGMENT = 12;
// _touchMove(touch: cc.Touch) {
const regions = [[]];
const pos = this.node_dirty.convertToNodeSpaceAR(touch.getLocation());

const count = DIG_FRAGMENT;
for (let index = 0; index < count; index++) {
const r = 2 * Math.PI * index / count;
const x = pos.x + DIG_RADIUS * Math.cos(r);
const y = pos.y + DIG_RADIUS * Math.sin(r);
regions[0].push([x, y]);
}

const result = PolyBool.difference({
regions: this._regions,
inverted: false
}, {
regions,
inverted: false
});
this._regions = result.regions;
this.draw();
```

## 填充颜色

```// private _drawPoly(ctx, poly) {
poly.forEach((pos, i) => {
if (i === 0)
ctx.moveTo(pos.x, pos.y);
else
ctx.lineTo(pos.x, pos.y);
ctx.close();
});
```

```// draw() {
const enabled_chains_points=[]
for (let index = 0; index < this._regions.length; index++) {
// 省略与上面相同 draw
enabled_chains_points[index] = poly.points;
}
this.graphics.clear(true);
const enabled_chains_points_sort = enabled_chains_points.map((curPoly, curPoly_i) => {
const count = enabled_chains_points.reduce((pre, nextPoly, nextPoly_i) => {
if ((curPoly_i != nextPoly_i)) {
const length = curPoly.length;
for (let i = 0; i < length; ++i) {
const p0 = curPoly[i];
if (!cc.Intersection.pointInPolygon(p0, nextPoly))
return pre;
}
return pre + 1;
}
return pre;
}, 0);

return { curPoly, count };
}).sort((a, b) => {
return a.count - b.count;
})
enabled_chains_points_sort.forEach(({ curPoly, count }) => {
this.graphics.fillColor = count % 2 === 0 ? cc.Color.ORANGE : cc.Color.BLACK;
this._drawPoly(this.graphics, curPoly);
this.graphics.fill();
})```

# 优化

< 未完待续 > 可关注【白玉无冰】获取最新进展！

# 小结

0 条评论

• ### 物理挖洞！涂抹地形! 优化篇！

物理挖洞！涂抹地形! 小鳄鱼爱洗澡！百战天虫 ！Cocos Creator ! 这篇文章介绍了如何实现。

• ### 物理刚体挖洞！另一种实现！

在 物理挖洞-优化篇 和 物理挖洞-实现篇 中介绍了一种用多边形链条组件(cc.PhysicsChainCollider)实现物理挖洞的方法。这次打算用多边形碰...

• ### 拇指投篮 ! Cocos Creator 3D !

为了能达到好的投篮效果，在网上找了一个投篮机参数，大致按照实际参数设置篮框大小，球的大小，以及篮框的位置。

• ### 物理挖洞！涂抹地形! 优化篇！

物理挖洞！涂抹地形! 小鳄鱼爱洗澡！百战天虫 ！Cocos Creator ! 这篇文章介绍了如何实现。

• ### Java的强引用，软引用，弱引用，虚引用及其使用场景

从 JDK1.2 版本开始，Java 把对象的引用分为四种级别，从而使程序能更加灵活的控制对象的生命周期。这四种级别由高到低依次为：强引用、软引用、弱引用和虚引...

• ### IO（上）

输入流，数据从源数据源流入程序的过程称为输入流。可以理解为从源数据源读取数据到程序的过程。

• ### 你知道Java的四种引用类型吗？

在Java中提供了四个级别的引用：强引用，软引用，弱引用和虚引用。在这四个引用类型中，只有强引用FinalReference类是包内可见，其他三种引用类型均为p...

• ### 干货 | ES6 系列之我们来聊聊装饰器

点击上方“腾讯NEXT学院”关注我们 Decorator 装饰器主要用于: 1. 装饰类 2. 装饰方法或属性 1 .装饰类 ...

• ### 开发中我们需要遵循的几个设计原则！（转）

在软件开发中，前人对软件系统的设计和开发总结了一些原则和模式， 不管用什么语言做开发，都将对我们系统设计和开发提供指导意义。本文主要将总结这些常见的原则和具体阐...

• ### 开发中我们需要遵循的几个设计原则！

在软件开发中，前人对软件系统的设计和开发总结了一些原则和模式， 不管用什么语言做开发，都将对我们系统设计和开发提供指导意义。本文主要将总结这些常见的原则和具体阐...