package Roguelike.Pathfinding; import Roguelike.Global; import Roguelike.Global.Passability; import Roguelike.Tiles.Point; import Roguelike.Util.EnumBitflag; import com.badlogic.gdx.math.MathUtils; import com.badlogic.gdx.utils.Array; public class BresenhamLine { public static Array<Point> lineNoDiag( int x0, int y0, int x1, int y1 ) { return lineNoDiag( x0, y0, x1, y1, null, false, 0, null, null ); } public static Array<Point> lineNoDiag( int x0, int y0, int x1, int y1, PathfindingTile[][] Grid, boolean checkPassable, int range, EnumBitflag<Passability> travelType, Object self ) { int xDist = Math.abs( x1 - x0 ); int yDist = -Math.abs( y1 - y0 ); int xStep = ( x0 < x1 ? +1 : -1 ); int yStep = ( y0 < y1 ? +1 : -1 ); int error = xDist + yDist; Array<Point> path = new Array<Point>(); path.add( Global.PointPool.obtain().set( x0, y0 ) ); while ( x0 != x1 || y0 != y1 ) { if ( 2 * error - yDist > xDist - 2 * error ) { // horizontal step error += yDist; x0 += xStep; } else { // vertical step error += xDist; y0 += yStep; } if ( Grid != null && (x0 < 0 || y0 < 0 || x0 >= Grid.length - 1 || y0 >= Grid[0].length - 1 || ( checkPassable && !Grid[x0][y0].getPassable( travelType, self ) ) ) ) { break; } path.add( Global.PointPool.obtain().set( x0, y0 ) ); } return path; } public static Array<Point> line( int x, int y, int x2, int y2, PathfindingTile[][] Grid, boolean checkPassable, int range, EnumBitflag<Passability> travelType, Object self ) { x = MathUtils.clamp( x, 0, Grid.length - 1 ); x2 = MathUtils.clamp( x2, 0, Grid.length - 1 ); y = MathUtils.clamp( y, 0, Grid[0].length - 1 ); y2 = MathUtils.clamp( y2, 0, Grid[0].length - 1 ); if ( x == x2 && y == y2 ) { return null; } int w = x2 - x; int h = y2 - y; int dx1 = 0, dy1 = 0, dx2 = 0, dy2 = 0; if ( w < 0 ) dx1 = -1; else if ( w > 0 ) dx1 = 1; if ( h < 0 ) dy1 = -1; else if ( h > 0 ) dy1 = 1; if ( w < 0 ) dx2 = -1; else if ( w > 0 ) dx2 = 1; int longest = Math.abs( w ); int shortest = Math.abs( h ); if ( !( longest > shortest ) ) { longest = Math.abs( h ); shortest = Math.abs( w ); if ( h < 0 ) dy2 = -1; else if ( h > 0 ) dy2 = 1; dx2 = 0; } int numerator = longest >> 1; int dist = range; Array<Point> path = new Array<Point>(); for ( int i = 0; i <= dist; i++ ) { path.add( Global.PointPool.obtain().set( x, y ) ); numerator += shortest; if ( !( numerator < longest ) ) { numerator -= longest; x += dx1; y += dy1; } else { x += dx2; y += dy2; } if ( x < 0 || y < 0 || x >= Grid.length - 1 || y >= Grid[0].length - 1 || ( checkPassable && !Grid[x][y].getPassable( travelType, self ) ) ) { break; } } return path; } }