125 lines
3.9 KiB
JavaScript
125 lines
3.9 KiB
JavaScript
class Grid {
|
|
constructor(config) {
|
|
this.width = config.width;
|
|
this.height = config.height;
|
|
this.collision = config.collision ?? {};
|
|
}
|
|
|
|
getCoords(tileX, tileY) {
|
|
const x = 0 + tileX * 24 + !(tileY % 2) * (24 / 2)
|
|
const y = 0 + tileY * (18 / 2);
|
|
|
|
return {
|
|
x,
|
|
y
|
|
};
|
|
}
|
|
|
|
getCell(roundedX, roundedY) {
|
|
const x = roundedX - 0;
|
|
const y = roundedY - 0;
|
|
const isEven = ((Math.floor(y / 9) * 9 - 9) / 18) % 1 !== 0;
|
|
const xw = isEven ? Math.floor(x / 24) : Math.floor((x + 12) / 24);
|
|
const xh = Math.floor(y / (18 / 2));
|
|
|
|
return {
|
|
xw,
|
|
xh
|
|
};
|
|
}
|
|
|
|
isValidNode(node) {
|
|
const blockedTile = this.collision[`${node.xw}-${node.xh}`];
|
|
return (!blockedTile && node.xw > 0 && node.xh > 0 && node.xw < this.width / 24 && node.xh < (this.height * 2) / 18);
|
|
}
|
|
|
|
randomNodeNear(nearToX, nearToY, radius) {
|
|
let r = radius * Math.sqrt(Math.random());
|
|
let a = 2 * Math.PI * Math.random();
|
|
|
|
let nearX = Math.round(r * Math.cos(a) + nearToX);
|
|
let nearY = Math.round(r * Math.sin(a) + nearToY);
|
|
|
|
let triedNode = this.getCell(nearX, nearY);
|
|
|
|
const { xw, xh } = triedNode;
|
|
let { x, y } = this.getCoords(xw, xh);
|
|
|
|
while (!this.isValidNode(triedNode) || (x === nearToX && y === nearToY) || Math.pow(x - nearToX, 2) + Math.pow(y - nearToY, 2) < Math.pow(500, 2)) {
|
|
r = radius * Math.sqrt(Math.random());
|
|
a = 2 * Math.PI * Math.random();
|
|
nearX = Math.round(r * Math.cos(a) + nearToX);
|
|
nearY = Math.round(r * Math.sin(a) + nearToY);
|
|
|
|
triedNode = this.getCell(nearX, nearY);
|
|
|
|
const { xw, xh } = triedNode;
|
|
const coords = this.getCoords(xw, xh);
|
|
x = coords.x;
|
|
y = coords.y;
|
|
};
|
|
|
|
return {
|
|
x,
|
|
y
|
|
};
|
|
}
|
|
|
|
randomNodeInArea(area) {
|
|
let xw = 0;
|
|
let xh = 0;
|
|
|
|
const minimumWidth = area.x - area.width / 2;
|
|
const maximumWidth = area.x + area.width / 2;
|
|
const minimumHeight = area.y - area.height / 2;
|
|
const maximumHeight = area.y + area.height / 2;
|
|
|
|
do {
|
|
xw = Math.floor((Math.random() * (maximumWidth - minimumWidth + 1) + minimumWidth) / 24);
|
|
xh = Math.floor((Math.random() * (maximumHeight - minimumHeight + 1) + minimumHeight) / (18 / 2));
|
|
} while (!this.isValidNode({ xw, xh }));
|
|
|
|
return this.getCoords(xw, xh);
|
|
}
|
|
|
|
randomNode(percentage) {
|
|
let xw = 0;
|
|
let xh = 0;
|
|
|
|
if (!percentage) percentage = 0;
|
|
percentage /= 200;
|
|
|
|
const minimumWidth = 0 + this.width * percentage;
|
|
const maximumWidth = this.width * (1 - percentage);
|
|
const minimumHeight = 0 + this.height * percentage;
|
|
const maximumHeight = this.height * (1 - percentage);
|
|
|
|
do {
|
|
xw = Math.floor((Math.random() * (maximumWidth - minimumWidth + 1) + minimumWidth) / 24);
|
|
xh = Math.floor((Math.random() * (maximumHeight - minimumHeight + 1) + minimumHeight) / (18 / 2));
|
|
} while (!this.isValidNode({ xw, xh }));
|
|
|
|
return this.getCoords(xw, xh);
|
|
}
|
|
|
|
getNodeNeighbours(node) {
|
|
const { xw, xh } = node;
|
|
let rightdown, leftdown, rightup, leftup;
|
|
|
|
if (node.xh % 2 !== 0) {
|
|
rightdown = { xw, xh: xh + 1 };
|
|
leftdown = { xw: xw - 1, xh: xh + 1 };
|
|
rightup = { xw, xh: xh - 1 };
|
|
leftup = { xw: xw - 1, xh: xh - 1 };
|
|
} else {
|
|
rightdown = { xw: xw + 1, xh: xh + 1 };
|
|
leftdown = { xw: xw, xh: xh + 1 };
|
|
rightup = { xw: xw + 1, xh: xh - 1 };
|
|
leftup = { xw: xw, xh: xh - 1 };
|
|
};
|
|
|
|
return [rightup, leftup, leftdown, rightdown];
|
|
}
|
|
};
|
|
|
|
module.exports = Grid; |