mapa
This commit is contained in:
124
src/workers/pathfinding.worker.js
Normal file
124
src/workers/pathfinding.worker.js
Normal file
@@ -0,0 +1,124 @@
|
||||
/* eslint-disable no-restricted-globals */
|
||||
|
||||
// Preprost A* Pathfinding v Web Workerju
|
||||
let grid = [];
|
||||
let width = 0;
|
||||
let height = 0;
|
||||
|
||||
self.onmessage = function (e) {
|
||||
const { type, payload, id } = e.data;
|
||||
|
||||
if (type === 'UPDATE_GRID') {
|
||||
grid = payload.grid;
|
||||
width = payload.width;
|
||||
height = payload.height;
|
||||
// console.log('🕷️ Worker: Grid updated', width, height);
|
||||
}
|
||||
else if (type === 'FIND_PATH') {
|
||||
if (!grid || grid.length === 0) {
|
||||
self.postMessage({ type: 'PATH_FOUND', id, path: [] });
|
||||
return;
|
||||
}
|
||||
const { startX, startY, endX, endY } = payload;
|
||||
const path = findPath(startX, startY, endX, endY);
|
||||
self.postMessage({ type: 'PATH_FOUND', id, path });
|
||||
}
|
||||
};
|
||||
|
||||
function findPath(startX, startY, endX, endY) {
|
||||
// Preverimo meje
|
||||
if (startX < 0 || startX >= width || startY < 0 || startY >= height) return [];
|
||||
if (endX < 0 || endX >= width || endY < 0 || endY >= height) return [];
|
||||
|
||||
// Če cilj ni prehoden, vrni prazno (ali najdi najbližjo točko - za zdaj prazno)
|
||||
if (!isWalkable(endX, endY)) return [];
|
||||
|
||||
const openSet = [];
|
||||
const closedSet = new Set();
|
||||
const cameFrom = new Map();
|
||||
|
||||
const gScore = new Map();
|
||||
const fScore = new Map();
|
||||
|
||||
const startKey = `${startX},${startY}`;
|
||||
const endKey = `${endX},${endY}`;
|
||||
|
||||
openSet.push({ x: startX, y: startY, f: heuristic(startX, startY, endX, endY) });
|
||||
gScore.set(startKey, 0);
|
||||
fScore.set(startKey, heuristic(startX, startY, endX, endY));
|
||||
|
||||
let iterations = 0;
|
||||
|
||||
while (openSet.length > 0) {
|
||||
iterations++;
|
||||
if (iterations > 1000) return []; // Safety break
|
||||
|
||||
// Najdi vozlišče z najnižjim fScore
|
||||
openSet.sort((a, b) => a.f - b.f);
|
||||
const current = openSet.shift();
|
||||
const currentKey = `${current.x},${current.y}`;
|
||||
|
||||
if (current.x === endX && current.y === endY) {
|
||||
return reconstructPath(cameFrom, current);
|
||||
}
|
||||
|
||||
closedSet.add(currentKey);
|
||||
|
||||
const neighbors = getNeighbors(current.x, current.y);
|
||||
for (const neighbor of neighbors) {
|
||||
const neighborKey = `${neighbor.x},${neighbor.y}`;
|
||||
if (closedSet.has(neighborKey)) continue;
|
||||
|
||||
const tentativeGScore = (gScore.get(currentKey) || 0) + 1;
|
||||
|
||||
if (tentativeGScore < (gScore.get(neighborKey) || Infinity)) {
|
||||
cameFrom.set(neighborKey, current);
|
||||
gScore.set(neighborKey, tentativeGScore);
|
||||
const f = tentativeGScore + heuristic(neighbor.x, neighbor.y, endX, endY);
|
||||
fScore.set(neighborKey, f);
|
||||
|
||||
if (!openSet.some(n => n.x === neighbor.x && n.y === neighbor.y)) {
|
||||
openSet.push({ x: neighbor.x, y: neighbor.y, f: f });
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return []; // Pot ni najdena
|
||||
}
|
||||
|
||||
function isWalkable(x, y) {
|
||||
if (x < 0 || x >= width || y < 0 || y >= height) return false;
|
||||
// Predpostavljamo 1D array: y * width + x. 0 = prehodno, 1 = ovira.
|
||||
return grid[y * width + x] === 0;
|
||||
}
|
||||
|
||||
function getNeighbors(x, y) {
|
||||
const neighbors = [];
|
||||
const dirs = [[0, 1], [0, -1], [1, 0], [-1, 0]]; // Samo 4 smeri (Manhattan)
|
||||
|
||||
for (const [dx, dy] of dirs) {
|
||||
const nx = x + dx;
|
||||
const ny = y + dy;
|
||||
if (isWalkable(nx, ny)) {
|
||||
neighbors.push({ x: nx, y: ny });
|
||||
}
|
||||
}
|
||||
return neighbors;
|
||||
}
|
||||
|
||||
function heuristic(x1, y1, x2, y2) {
|
||||
return Math.abs(x1 - x2) + Math.abs(y1 - y2);
|
||||
}
|
||||
|
||||
function reconstructPath(cameFrom, current) {
|
||||
const totalPath = [current];
|
||||
let currentKey = `${current.x},${current.y}`;
|
||||
|
||||
while (cameFrom.has(currentKey)) {
|
||||
current = cameFrom.get(currentKey);
|
||||
currentKey = `${current.x},${current.y}`;
|
||||
totalPath.unshift(current);
|
||||
}
|
||||
return totalPath;
|
||||
}
|
||||
Reference in New Issue
Block a user