Random Connected Area - Mix
https://xcoder.in/2018/04/02/random-connected-area/#生成「胖胖的」区域
by XadillaX
HTML
<script src="https://cdnjs.cloudflare.com/ajax/libs/fbbk-json/1.1.1/fjson.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.5/lodash.min.js"></script>
<input id="length" placeholder="宽高" />
<input id="need-area" placeholder="填充面积" />
<button id="gen">生成</button>
<br />
<canvas id="cvs"></canvas><br /><br />
<img style="display: none;" id="tile" src="http://xcoder-7niu.nbut.ac.cn/basictiles.png" />
CSS
body {
background: #20262E;
padding: 20px;
font-family: Helvetica;
}
#banner-message {
background: #fff;
border-radius: 4px;
padding: 20px;
font-size: 25px;
text-align: center;
transition: all 0.2s;
margin: 0 auto;
width: 300px;
}
button {
background: #0084ff;
border: none;
border-radius: 5px;
padding: 8px 14px;
font-size: 15px;
color: #fff;
}
#banner-message.alt {
background: #0084ff;
color: #fff;
margin-top: 40px;
width: 200px;
}
#banner-message.alt button {
background: #fff;
color: #000;
}
JavaScript
function random(max) {
return Math.round(Math.random() * max);
}
class Filler3 {
constructor(length, needArea) {
this.length = length;
this.needArea = needArea;
}
_getContiguous(frontier) {
return Filler3.DIRS.map(dir => ({
x: frontier.x + dir[0],
y: frontier.y + dir[1]
}));
}
_processFrontier(coor) {
// 获取接壤坐标
const contiguousOfNewCoor = this._getContiguous(coor).filter(coor => {
if (coor.x < 0 || coor.y < 0 || coor.x >= this.length || coor.y >= this.length) return false;
return true;
});
// 若有一个接壤点为空,就认为当前坐标是边界,若是边界则把当前坐标加入对象
if (contiguousOfNewCoor.reduce((ret, coor) => {
if (this.map[coor.x][coor.y] === "x") return ret;
return true;
}, false)) {
this.frontiers[`${coor.x}:${coor.y}`] = true;
this.frontierCount++;
}
// 再检查接壤的坐标是否继续为边界
for (let i = 0; i < contiguousOfNewCoor.length; i++) {
const cur = contiguousOfNewCoor[i];
const isFrontier = this._getContiguous(cur).filter(coor => {
if (coor.x < 0 || coor.y < 0 || coor.x >= this.length || coor.y >= this.length) return false;
return true;
}).reduce((ret, coor) => {
if (this.map[coor.x][coor.y] === "x") return ret;
return true;
}, false);
// 若不是边界的话,只管删除
if (!isFrontier && this.frontiers[`${cur.x}:${cur.y}`]) {
delete this.frontiers[`${cur.x}:${cur.y}`];
this.frontierCount--;
}
}
}
_getUsableContiguous(coor) {
// _getContiguous 算出接壤坐标,filter 去除无用坐标
return this._getContiguous({
x: coor.x,
y: coor.y
}).filter(coor => {
if (coor.x < 0 || coor.y < 0 || coor.x >= this.length || coor.y >= this.length) return false;
if...