232 lines
4.5 KiB
JavaScript
232 lines
4.5 KiB
JavaScript
const timer = ms => new Promise(res => setTimeout(res, ms))
|
|
|
|
var cols = 9
|
|
var rows = 9
|
|
|
|
let grid = new Array(cols);
|
|
|
|
let openSet = [];
|
|
let closedSet = [];
|
|
|
|
let start;
|
|
let end;
|
|
let path = [];
|
|
|
|
|
|
function generateClickMap() {
|
|
var clickMap = document.getElementById('click-map')
|
|
for (let i = 0; i < rows; i++) {
|
|
for (let j = 0; j < cols; j++) {
|
|
var area = document.createElement('area')
|
|
area.shape = 'rect'
|
|
area.href = '#'
|
|
area.addEventListener('click', function (event) {
|
|
if (j > 7) {
|
|
pathfind(i, j - 1)
|
|
} else {
|
|
pathfind(i, j)
|
|
}
|
|
})
|
|
area.coords = `${i * spriteSize},${j * spriteSize},${(i + 1) * spriteSize},${(j + 1) * spriteSize}`
|
|
clickMap.appendChild(area)
|
|
}
|
|
}
|
|
}
|
|
|
|
generateClickMap()
|
|
|
|
function heuristic(position0, position1) {
|
|
let d1 = Math.abs(position1.x - position0.x);
|
|
let d2 = Math.abs(position1.y - position0.y);
|
|
|
|
return d1 + d2;
|
|
}
|
|
|
|
|
|
class GridPoint {
|
|
constructor(x, y) {
|
|
this.x = x;
|
|
this.y = y;
|
|
this.f = 0;
|
|
this.g = 0;
|
|
this.h = 0;
|
|
this.neighbors = [];
|
|
this.parent = undefined;
|
|
}
|
|
|
|
updateNeighbors(grid) {
|
|
let i = this.x;
|
|
let j = this.y;
|
|
var tmpNeighbor;
|
|
if (i < cols - 1) {
|
|
tmpNeighbor = grid[i + 1][j]
|
|
if (!player.isBoundary([tmpNeighbor.x, tmpNeighbor.y])) {
|
|
this.neighbors.push(tmpNeighbor);
|
|
}
|
|
}
|
|
if (i > 0) {
|
|
tmpNeighbor = grid[i - 1][j]
|
|
if (!player.isBoundary([tmpNeighbor.x, tmpNeighbor.y])) {
|
|
this.neighbors.push(tmpNeighbor);
|
|
}
|
|
}
|
|
if (j < rows - 1) {
|
|
tmpNeighbor = grid[i][j + 1]
|
|
if (!player.isBoundary([tmpNeighbor.x, tmpNeighbor.y])) {
|
|
this.neighbors.push(tmpNeighbor);
|
|
}
|
|
}
|
|
if (j > 0) {
|
|
tmpNeighbor = grid[i][j - 1]
|
|
if (!player.isBoundary([tmpNeighbor.x, tmpNeighbor.y])) {
|
|
this.neighbors.push(tmpNeighbor);
|
|
}
|
|
}
|
|
};
|
|
}
|
|
|
|
|
|
function init(destX, destY) {
|
|
|
|
for (let i = 0; i < cols; i++) {
|
|
grid[i] = new Array(rows);
|
|
}
|
|
|
|
for (let i = 0; i < cols; i++) {
|
|
for (let j = 0; j < rows; j++) {
|
|
grid[i][j] = new GridPoint(i, j);
|
|
}
|
|
}
|
|
|
|
for (let i = 0; i < cols; i++) {
|
|
for (let j = 0; j < rows; j++) {
|
|
grid[i][j].updateNeighbors(grid);
|
|
}
|
|
}
|
|
|
|
start = grid[player.canvasX][player.canvasY];
|
|
end = grid[destX][destY]
|
|
|
|
openSet.push(start);
|
|
}
|
|
|
|
|
|
function search(destX, destY) {
|
|
path = [];
|
|
init(destX, destY);
|
|
while (openSet.length > 0) {
|
|
|
|
let lowestIndex = 0;
|
|
for (let i = 0; i < openSet.length; i++) {
|
|
if (openSet[i].f < openSet[lowestIndex].f) {
|
|
lowestIndex = i;
|
|
}
|
|
}
|
|
let current = openSet[lowestIndex];
|
|
|
|
if (current === end) {
|
|
let temp = current;
|
|
path.push(temp);
|
|
while (temp.parent) {
|
|
path.push(temp.parent);
|
|
temp = temp.parent;
|
|
}
|
|
|
|
return path.reverse()
|
|
}
|
|
|
|
|
|
openSet.splice(lowestIndex, 1);
|
|
|
|
closedSet.push(current);
|
|
|
|
let neighbors = current.neighbors;
|
|
|
|
for (let i = 0; i < neighbors.length; i++) {
|
|
let neighbor = neighbors[i];
|
|
|
|
if (!closedSet.includes(neighbor)) {
|
|
let possibleG = current.g + 1;
|
|
|
|
if (!openSet.includes(neighbor)) {
|
|
openSet.push(neighbor);
|
|
} else if (possibleG >= neighbor.g) {
|
|
continue;
|
|
}
|
|
|
|
neighbor.g = possibleG;
|
|
neighbor.h = heuristic(neighbor, end);
|
|
neighbor.f = neighbor.g + neighbor.h;
|
|
neighbor.parent = current;
|
|
}
|
|
}
|
|
}
|
|
|
|
return [];
|
|
}
|
|
|
|
async function pathfind(destX, destY) {
|
|
|
|
var isBoundary = player.isBoundary([destX, destY])
|
|
|
|
if (isBoundary) {
|
|
var tmpDestX = destX
|
|
var tmpDestY = destY
|
|
var newDest = boundaryMap[String(destX) + String(destY)]
|
|
destX = newDest[0]
|
|
destY = newDest[1]
|
|
}
|
|
|
|
var newPath = search(destX, destY)
|
|
for (let i = 0; i < newPath.length; i++) {
|
|
changeDir(newPath[i].x, newPath[i].y)
|
|
|
|
player.canvasX = newPath[i].x
|
|
player.canvasY = newPath[i].y
|
|
|
|
if (isBoundary && i === newPath.length - 1) {
|
|
changeDir(tmpDestX, tmpDestY)
|
|
}
|
|
await timer(100)
|
|
}
|
|
|
|
if (destX === 0 && destY === 0 || destX === 1 && destY === 0) {
|
|
player.direction = 'up'
|
|
portfolio.show()
|
|
}
|
|
|
|
if (destX === 7 && destY === 0 || destX === 8 && destY === 0) {
|
|
player.direction = 'up'
|
|
games.show()
|
|
}
|
|
|
|
if (destX === 2 && destY === 4 || destX === 3 && destY === 4) {
|
|
player.direction = 'up'
|
|
terminal.show()
|
|
}
|
|
|
|
if (destX === 4 && destY === 4) {
|
|
player.direction = 'up'
|
|
resume.show()
|
|
}
|
|
|
|
if (destX === 0 && destY === 6 || destX === 1 && destY === 6) {
|
|
player.direction = 'down'
|
|
music.show()
|
|
}
|
|
|
|
}
|
|
|
|
function changeDir(destX, destY) {
|
|
if (destX > player.canvasX) {
|
|
player.direction = 'right'
|
|
} else if (destX < player.canvasX) {
|
|
player.direction = 'left'
|
|
}
|
|
|
|
if (destY > player.canvasY) {
|
|
player.direction = 'down'
|
|
} else if (destY < player.canvasY) {
|
|
player.direction = 'up'
|
|
}
|
|
}
|