qiao / PathFinding.js

A comprehensive path-finding library for grid based games
http://qiao.github.io/PathFinding.js/visual/
8.42k stars 1.32k forks source link

Best way to use PathFinding.js in Angular 6+ #167

Open luizdanielmlima opened 5 years ago

luizdanielmlima commented 5 years ago

Hello, thank you for this library! I´d like to use it in Angular 6, but I´m not sure how to install it. What I did:

1) "npm install pathfinding"

2) In the angular.json I added it: "scripts": ["node_modules/paper/dist/paper-full.min.js", "node_modules/pathfinding/src/PathFinding.js"]

3) In my component, I tried to import: import { Grid, Finder } from "pathfinding";

But I get an error when I compile it, with "ng serve": PathFinding.js:1 Uncaught ReferenceError: module is not defined at PathFinding.js:1

Is it possible to use it in Angular? If so, what´s the best way to do it? Any help would be very welcome!

(I´m building an interactive table app for shopping/malls and I´m trying to build the wayfinding module)

Thanks in advance!

brean commented 5 years ago

I have not used angular in quite some time but I just installed it and tried around a bit. The Pathfinding.js file in the src-folder of the installed package is the entry point for the source code that gulp uses to build the lib, you need the transpiled version. So you either checkout Pathfinding.js using git and transpile it using gulp or you use the compiled version from the "visual" folder: scripts: ["node_modules/pathfinding/visual/lib/pathfinding-browser.min.js", ...] that's the fastest hack I can think of and your import works with that, I tried import { Grid, Finder, AStarFinder } from "pathfinding";. but I suggest you build the lib using gulp and copy the build file somewhere into your angular project and use that because the file in the visual-folder is not the newest version.

P.S. I am curious how you store the shopping-mall building data (walls, rooms etc.)? Do you have an IFC file of the mall or are you using photographs of floor plan for the building?

luizdanielmlima commented 5 years ago

Hi Andreas,

Thank you for repplying so quickly. I´ve never used Gulp, so I will start with the pathfinding-browser.min.js first, for some quick tests.

About the shopping-mall data, I´m just using the floor plan image (raster) "behind" the grid (through a for-loop of boxes that I´m drawing with paper.js). So in my editor app I will have to set-up the obstacles using the image as a reference.

I still don´t know exactly how to save the data from the boxes to something I can use in the pathfinding, like it the first box (top-left) is the point 0,0 in the matrix and so on? Any tip? I noticed you used raphael.js for the drawing in your demo, is is faster or better than paper.js?

Thanks in advance!

brean commented 5 years ago

Hi,

It is not my demo, I am not the developer of Pathfinding.js, I just used it as basis for my python-pathfinding implementation. For raphael vs. paper, i suggest you take a look at this stackoverflow discussion. I think it depends on your specific device for possible performance issues (big screen without graphics card and small CPU might be a bit hard for canvas rendering), but besides that you can use what you feel most comfortable with.

I don't know exactly what you like to model, but you can have rooms or spaces (rooms split into smaller areas) that you use as nodes for pathfinding.js, with the first space in the top-left corner and then others around, I assume a grid-structure works for you and might be the best solution, so you can just create a grid of spaces and let pathfinding.js do its magic without changing anything. Otherwise you might want to implement your own functions to get neighbouring nodes and calculate distances.

luizdanielmlima commented 5 years ago

Hi,

Thank you for the link for the discussion between Paper.js and Raphael.js, it was really valuable. Yesterday I managed to make the pathfinding work, the grid structure seems to work ... for now, I will keep testing it. One last doubt though: just like the demo, I let the user define the walls by clicking in a box in the grid . I´d like to save this info in a array so I can later load the entire grid configuration in the app. In the docs it says I can use a matrix, in:

var matrix = [ [0, 0, 0, 1, 0], [1, 0, 0, 0, 1], [0, 0, 1, 0, 0], ]; var grid = new PF.Grid(matrix);

But I don´t understand why the items have 5 numbers, I thought each item should have only x,y and the boolean (isWalkable).. any help?

Thanks!

brean commented 5 years ago

the y and x values are defined by the position in the 2d-array/matrix and the value at that position defines if it is walkable or not. In JavaScript 0 can be interpreted as false and 1 as true, so it does not make a difference. matrix[y][x] = 1; means that there is an obstacle at position x|y.

luizdanielmlima commented 5 years ago

Hi, thanks for the help, I don´t know why I didn´t see that before... so obvious lol ;-)

khelsisura commented 5 years ago

Hello Mr. @luizdanielmlima, I am planning to use pathfinding.js also using angular js and i can't find any resources that can give me some idea to run it since it was made using gulp, do you find any solutions?

luizdanielmlima commented 5 years ago

Hi @harveyelsisura ,

I use Angular 7 (not Angular JS), but the way it worked for was as following:

1) Install via NPM: "npm install pathfinding"

2) In the angular.json I added it: "scripts": ["node_modules/pathfinding/visual/lib/pathfinding-browser.min.js"]

3) In my component, I import it: import { Grid, Finder, AStarFinder } from "pathfinding";

4) Then you use it like explained in Qiao´s project Github, by instantiating the Grid, etc.:

let grid: Grid; let finder: Finder; let matrix: any[]; let startPoint = [0,0]; let endPoint = [5,3];

matrix = [ [0, 0, 0, 1, 0], [1, 0, 0, 0, 1], [0, 0, 1, 0, 0], ]; grid = new Grid(matrix); finder = new AStarFinder({ allowDiagonal: true });

let tempGrid = grid.clone(); let pathCalc = finder.findPath( startPoint[0], startPoint[1], endPoint[0], endPoint[1], tempGrid );

khelsisura commented 5 years ago

Yes i mean angular 7 by the way thank you for a quick response mr. @luizdanielmlima

mlusca commented 5 years ago

Oi @luizdanielmlima O seu está funcionando normal? tenho uma matrix let matrix = [ [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] ]; let grid = new Grid(11, 11, matrix); let finder = new AStarFinder(); let path = finder.findPath(0, 5, 10, 5, grid);

Que vai do 05 até o 10 05, mas tem uma wall no meio e mesmo assim ela está passando por cima..

luizdanielmlima commented 5 years ago

Olá,

Primeiramente, acho que você precisa definir o grid com apenas:

let grid = new Grid(matrix);

E também é importante clonar esse grid, porque após rodar o pathfinding ele altera o grid original:

let tempGrid = grid.clone();

Então no pathfinding você usa esse tempGrid, assim:

let path = finder.findPath(0, 5, 10, 5, tempGrid)

Por último você está saindo do ponto (0,5) e indo para o (10,5). É uma linha reta, onde não tem nenhum obstáculo mesmo. Talvez teste saindo do ponto (0,0) para o canto inferior direito, ou seja, o (11, 11). No código, ficaria assim:

let path = finder.findPath(0, 0, 11, 11, tempGrid);

Ou seja os 2 primeiros parâmetros no "findPath()" são as coords. do 1o ponto (startPoint), depois vem as coords do 2o ponto (endPoint) e por último qual o grid a ser usado.

Bom, espero ter ajudado, tomara que funcione! ;-)

Luiz Daniel Lima