You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

160 lines
4.5 KiB

2 years ago
class Grid{
constructor(settings, cellCount, difficulty, randomDirection){
this.margin = settings.margin;
this.cellCount = createVector(cellCount, cellCount);
this.nodes = [];
for (let x = 0; x < this.cellCount.x; x++){
let column = [];
for (let y = 0; y < this.cellCount.y; y++){
let forbidden = ranBool(7 - difficulty);
if (!randomDirection){
let allowed = [
{x: 0, y: 0},
{x: 1, y: 0},
{x: 1, y: 1},
{x: 0, y: 1},
{x: this.cellCount.x - 1, y: this.cellCount.y - 1},
{x: this.cellCount.x - 1, y: this.cellCount.y - 2},
{x: this.cellCount.x - 2, y: this.cellCount.y - 2},
{x: this.cellCount.x - 2, y: this.cellCount.y - 1},
];
allowed.forEach(a => {
if (x === a.x && y === a.y){
forbidden = false;
}
});
}
column.push(new PathNode(x, y, forbidden));
}
this.nodes.push(column);
}
this.nodes.forEach(x => x.forEach(n => n.connectToSuccessors(this.nodes)));
let nodes = [];
this.nodes.forEach(x => nodes.push(...x.filter(n => n.isForbidden)));
this.forbiddenNodes = nodes;
nodes = [];
this.nodes.forEach(x => nodes.push(...x.filter(n => !n.isForbidden)));
this.allowedNodes = nodes;
}
get size(){
return Math.min(width - this.margin * 2, height - this.margin * 2);
}
get nodeSize(){
return {
x: this.size / this.cellCount.x,
y: this.size / this.cellCount.y
};
}
display(appearance, linesAreVisible){
translate(this.margin, this.margin);
if (linesAreVisible){
let size = this.size;
stroke(100);
strokeWeight(1);
for (let x = 0; x <= size + 1; x += size / this.cellCount.x){
line(x, 0, x, size);
}
for (let y = 0; y <= size + 1; y += size / this.cellCount.y){
line(0, y, size, y);
}
}
translate(this.nodeSize.x / 2, this.nodeSize.y / 2);
scale(this.nodeSize.x, this.nodeSize.y);
noStroke();
fill(200, 50, 50);
for (let n of this.forbiddenNodes){
let x = n.pos.x;
let y = n.pos.y;
if (appearance === 'Circles'){
let r = 0.5;
ellipse(x, y, r * 2);
}
if (appearance === 'Rectangles'){
rect(x - 0.5, y - 0.5, 1, 1);
}
}
}
getAllowedNodesDistantTo(otherNode){
return this.allowedNodes.filter(n => n.pos.dist(otherNode.pos) > Math.max(this.cellCount.x, this.cellCount.y) / 2);
}
}
class PathNode{
constructor(x, y, isForbidden){
this.pos = createVector(x, y);
this.isForbidden = isForbidden;
}
get distanceToTarget(){
return this.pos.dist(game.targetNode.pos);
}
setMovement(movement){
this.isDiagonalAllowed = false;
this.isStraightAllowed = false;
switch (movement){
case "0":
this.isStraightAllowed = true;
break;
case "1":
this.isDiagonalAllowed = true;
break;
case "2":
this.isStraightAllowed = true;
this.isDiagonalAllowed = true;
break;
}
}
connectToSuccessors(nodes){
let allowed = [], successors = [];
if (this.isStraightAllowed){
allowed.push(
{x: 1, y: 0},
{x: 0, y: 1},
{x: -1, y: 0},
{x: 0, y: -1}
);
}
if (this.isDiagonalAllowed){
allowed.push(
{x: 1, y: 1},
{x: 1, y: -1},
{x: -1, y: 1},
{x: -1, y: -1}
);
}
allowed.forEach(a => {
let column = nodes[this.pos.x + a.x];
if (column){
let node = column[this.pos.y + a.y];
if (node){
if (!node.isForbidden){
successors.push(node);
}
}
}
});
this.successors = successors;
}
}