Here is jus my code in haxe implementing GBVF pathfinding class.
package com.nailedgames; import flash.geom.Point; typedef PathTile = { var x:Int; var y:Int; var step:Int; } class GBVF_pathfinding { private var _tile_width:Int; private var _tile_height:Int; private var _field_width:Int; private var _field_height:Int; private var _field_wtiles:Int; private var _field_htiles:Int; private var _distances:Array<Int>; private var _vectors:Array<Point>; public var vectors(get,null):Array<Point>; public function new() { } function get_vectors():Array<Point> { return _vectors; } public function Init(tile_width:Int, tile_height:Int, field_width:Int, field_height:Int) { _tile_width = tile_width; _tile_height = tile_height; _field_width = field_width; _field_height = field_height; _field_wtiles = Std.int(field_width/tile_width); _field_htiles = Std.int(field_height/tile_height); _distances = new Array(); for(i in 0..._field_htiles) for(j in 0..._field_wtiles) _distances.push(-1); } public function Calculate_field(walls_map:Array<Int>, x_block:Int, y_block:Int):Array<Point> { for(i in 0..._distances.length) if(walls_map[i] == 1) _distances[i] = -3; else _distances[i] = -1; Mark_tiles([{x:x_block, y:y_block, step:0}]); return _vectors; } private function Mark_tiles(points:Array<Pathtile>):Void { if(Lambda.empty(points)) return; var neighbours:Array<Pathtile> = new Array<Pathtile>(); for(point in points) { _distances[point.x + point.y*_field_wtiles] = point.step; if(point.x > 0) { if(_distances[(point.x-1) + point.y*_field_wtiles] == -1) { neighbours.push({x:point.x-1, y:point.y, step:point.step+1}); _distances[(point.x-1) + point.y*_field_wtiles] = -2; } } if(point.x < (_field_wtiles-1)) { if(_distances[(point.x+1) + point.y*_field_wtiles] == -1) { neighbours.push({x:point.x+1, y:point.y, step:point.step+1}); _distances[(point.x+1) + point.y*_field_wtiles] = -2; } } if(point.y > 0) { if(_distances[point.x + (point.y-1)*_field_wtiles] == -1) { neighbours.push({x:point.x, y:point.y-1, step:point.step+1}); _distances[point.x + (point.y-1)*_field_wtiles] = -2; } } if(point.y < (_field_htiles-1)) { if(_distances[point.x + (point.y+1)*_field_wtiles] == -1) { neighbours.push({x:point.x, y:point.y+1, step:point.step+1}); _distances[point.x + (point.y+1)*_field_wtiles] = -2; } } } Mark_tiles(neighbours); Assign_vectors(); } private function Assign_vectors():Void { _vectors = new Array<Point>(); for(y_tile in 0..._field_htiles) { for(x_tile in 0..._field_wtiles) { if(_distances[x_tile + y_tile*_field_wtiles] > 0) { var left_dist:Int = _distances[x_tile + y_tile*_field_wtiles]+1; var right_dist:Int = _distances[x_tile + y_tile*_field_wtiles]+1; var up_dist:Int = _distances[x_tile + y_tile*_field_wtiles]+1; var down_dist:Int = _distances[x_tile + y_tile*_field_wtiles]+1; if((x_tile > 0) && (_distances[(x_tile-1) + y_tile*_field_wtiles] >= 0)) left_dist = _distances[(x_tile-1) + y_tile*_field_wtiles]; if((x_tile < (_field_wtiles-1)) && (_distances[(x_tile+1) + y_tile*_field_wtiles] >= 0)) right_dist = _distances[(x_tile+1) + y_tile*_field_wtiles]; if((y_tile > 0) && (_distances[x_tile + (y_tile-1)*_field_wtiles] >= 0)) up_dist = _distances[x_tile + (y_tile-1)*_field_wtiles]; if((y_tile < (_field_htiles-1)) && (_distances[x_tile + (y_tile+1)*_field_wtiles] >= 0)) down_dist = _distances[x_tile + (y_tile+1)*_field_wtiles]; _vectors.push(new Point( left_dist - right_dist, up_dist - down_dist)); }else{ _vectors.push(new Point(0,0)); } } } } }Here is usage example:
var tile_width:Int = 40; var tile_height:Int = 40; var field_width:Int = 800; var field_height:Int = 600; gbvf = new GBVF_pathfinding(); walls_map = [ 0,0,0,0,1,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,1,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,1,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1, 0,0,1,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,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,0,0,0,0,0,1,0,0,0,0,0,0, 0,0,0,0,0,0,0,1,0,0,0,0,0,1,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,1,0,0,0,0,0,1,0,0,0,0,0,0, 0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0, ]; gbvf.Init(tile_width, tile_height, field_width, field_height); var vectors:Array<Point> = gbvf.Calculate_field(walls_map, x_block, y_block);As a result you will have array of vectors coordinates relative to the center of tiles.