My old range calculation code (found here) was, as I admitted, slow and... well... rubbish.
Completely rewritten. Almost no trace of the old code whatsoever, and I do it in a far, far, far simpler manner now.
Again - licensed under Lachlan's Very Public License, being a modified Unlicense. Do whatever you want with it, don't blame me if something goes wrong, and donations/attribution/a comment saying its useful would be really nice.
public List<coord> GetRange(coord start, int range, bool PlayerCollides = true) { List<coord> returnlist = new List<coord>(); int[,] distances = new int[range * 2 + 3, range * 2 + 3]; for (int ix = 0; ix < distances.GetLength(0); ix++) { for (int iy = 0; iy < distances.GetLength(1); iy++) { // -1 is not yet visited // -2 is a collision point distances[ix, iy] = (PlayerCollides ? (CheckCollision(ix + start.X - range - 1, iy + start.Y - range - 1)) : (TileCollides(ix + start.X - range - 1, iy + start.Y - range - 1))) ? -2 : -1; } } const int STRAIGHT_COST = 10; const int DIAG_COST = 14; distances[range + 1 ,range + 1] = 0; for (int i = 1; i <= range; i++) { for (int jx = -i; jx <= i; jx++) { for (int jy = -i; jy <= i; jy++) { if (distances[jx + range + 1, jy + range + 1] == -1) { int minDistance = int.MaxValue; for (int lx = -1; lx < 2; lx++) { for (int ly = -1; ly < 2; ly++) { if (!(lx == 0 && ly == 0)) { int distance = distances[jx + range + lx + 1, jy + range + ly + 1]; if (distance >= 0) { minDistance = Math.Min(minDistance, distance + (((lx == 0) || (ly == 0)) ? STRAIGHT_COST : DIAG_COST)); } } } } if (minDistance != int.MaxValue) { distances[jx + range + 1, jy + range + 1] = minDistance; if (minDistance <= (range * STRAIGHT_COST)) { returnlist.Add(new coord(jx + start.X, jy + start.Y)); } } } }} } return returnlist; }
0 comments:
Post a comment