public void BuildPoints() { var oldWidth = _game.Level.Tiles.Length; var oldHeight = _game.Level.Tiles[0].Length; _width = oldWidth * Divisor; _height = oldHeight * Divisor; for (var i = 0; i < oldWidth; ++i) { for (var j = 0; j < oldHeight; ++j) { if (_game.Level.Tiles[i][j] == Tile.JumpPad) { for (int i1 = Math.Max(0, i * Divisor - UnitHalfWidth); i1 <= Math.Min((i + 1) * Divisor + UnitHalfWidth, _width); ++i1) { for (int j1 = Math.Max(0, j * Divisor - UnitHeight); j1 <= (j + 1) * Divisor; ++j1) { _jumpPoints.Set(NavigationUtils.EncodePoint(i1, j1), true); } } } if (_game.Level.Tiles[i][j] == Tile.Ladder) { for (int i1 = Math.Max(0, i * Divisor + 1), k = 0; i1 <= Math.Min((i + 1) * Divisor - 1, _width); ++i1, ++k) { for (int j1 = Math.Max(0, j * Divisor - UnitHalfHeight); j1 <= (j + 1) * Divisor; ++j1) { _groundPoints.Set(NavigationUtils.EncodePoint(i1, j1), true); _dropPoints.Set(NavigationUtils.EncodePoint(i1, j1), true); _ladderPoints.Set(NavigationUtils.EncodePoint(i1, j1), true); } } } if (_game.Level.Tiles[i][j] == Tile.Platform) { for (int k = Math.Max(0, i * Divisor - UnitHalfWidth); k <= Math.Min((i + 1) * Divisor + UnitHalfWidth, _width); ++k) { _groundPoints.Set(NavigationUtils.EncodePoint(k, (j + 1) * Divisor), true); _dropPoints.Set(NavigationUtils.EncodePoint(k, (j + 1) * Divisor), true); } } if (_game.Level.Tiles[i][j] == Tile.Wall) { for (int i1 = Math.Max(0, i * Divisor - UnitHalfWidth); i1 <= Math.Min((i + 1) * Divisor + UnitHalfWidth, _width); ++i1) { for (int j1 = Math.Max(0, j * Divisor - UnitHeight); j1 < (j + 1) * Divisor; ++j1) { _blockPoints.Set(NavigationUtils.EncodePoint(i1, j1), true); } } var bottomExists = j * Divisor > UnitHeight; for (int i1 = Math.Max(0, i * Divisor - UnitHalfWidth); i1 <= Math.Min((i + 1) * Divisor + UnitHalfWidth, _width); ++i1) { _groundPoints.Set(NavigationUtils.EncodePoint(i1, (j + 1) * Divisor), true); if (bottomExists) { _bottomPoints.Set(NavigationUtils.EncodePoint(i1, j * Divisor - UnitHeight - 1), true); } } if (bottomExists) { if (i * Divisor > UnitHalfWidth) { _sharpLeftPoints.Set( NavigationUtils.EncodePoint(i * Divisor - UnitHalfWidth - 1, j * Divisor - UnitHeight - 1), true); } if ((i + 1) * Divisor < _width - UnitHalfWidth) { _sharpRightPoints.Set( NavigationUtils.EncodePoint((i + 1) * Divisor + UnitHalfWidth + 1, j * Divisor - UnitHeight - 1), true); } } } } } }
public List <int> FindPath(int s, int fx, int fy, int dist = 0) { if (_lastPath != null && fx == _lastFx && fy == _lastFy && _lastPath.Count > 0) { var(sx, sy, jj, pp) = NavigationUtils.DecodeState(s); var(sx1, sy1, jj1, pp1) = NavigationUtils.DecodeState(_lastPath[0]); if (sx == sx1 && sy == sy1) { _lastPath.RemoveAt(0); return(_lastPath); } } var order = new LinkedList <int>(); order.AddLast(s); var parent = new Dictionary <int, int>(); parent.Add(s, s); int f = -1; while (order.Count > 0) { var currentCode = order.First.Value; order.RemoveFirst(); var(x, y, j, p) = NavigationUtils.DecodeState(currentCode); if (Math.Abs(x - fx) <= dist && Math.Abs(y - fy) <= dist) { f = currentCode; break; } var currentPoint = NavigationUtils.EncodePoint(x, y); for (int move = 0; move < PointMaster.Moves; ++move) { if (!_pointMaster.IsValidMove(currentPoint, move)) { continue; } var newCode = ApplyMove(x, y, j, p, move); if (newCode < 0 || parent.ContainsKey(newCode)) { continue; } var(nx, ny, nj, np) = NavigationUtils.DecodeState(newCode); parent[newCode] = currentCode; order.AddLast(newCode); } if (j == 1 && p == 1) { var newCode = NavigationUtils.EncodeState(x, y, 0, 0); if (newCode < 0 || parent.ContainsKey(newCode)) { continue; } parent[newCode] = currentCode; order.AddLast(newCode); } } if (f == -1) { return(null); } var path = new List <int>(); var cur = f; while (cur != s) { cur = parent[cur]; if (cur == s) { break; } path.Add(cur); } path.Reverse(); order.Clear(); parent.Clear(); _lastFx = fx; _lastFy = fy; _lastPath = path; return(path); }
public bool IsPointLadder(int x, int y) => _ladderPoints.Get(NavigationUtils.EncodePoint(x, y));
public bool IsValidMove(int x, int y, int move) => _goodMoves.Get(NavigationUtils.EncodePoint(x, y) * Moves + move);
public bool IsPointBottom(int x, int y) => _bottomPoints.Get(NavigationUtils.EncodePoint(x, y));
public bool IsSharpRight(int x, int y) => _sharpRightPoints.Get(NavigationUtils.EncodePoint(x, y));
public bool IsPointDrop(int x, int y) => _dropPoints.Get(NavigationUtils.EncodePoint(x, y));
public bool IsPointJump(int x, int y) => _jumpPoints.Get(NavigationUtils.EncodePoint(x, y));
public bool IsPointGround(int x, int y) => _groundPoints.Get(NavigationUtils.EncodePoint(x, y));
public bool IsPointBlocking(int x, int y) => _blockPoints.Get(NavigationUtils.EncodePoint(x, y));
public void CheckMoves() { for (int x = 0; x <= _width; ++x) { for (int y = 0; y <= _height; ++y) { var point = NavigationUtils.EncodePoint(x, y); var offset = point * Moves; if (!IsPointJump(point)) { if (x > 0 && IsPointGround(point) && !IsPointBlocking(x - 1, y)) { _goodMoves.Set(offset + 0, true); } if (x < _width && IsPointGround(point) && !IsPointBlocking(x + 1, y)) { _goodMoves.Set(offset + 1, true); } if (x > 0 && y < _height && IsPointGround(point) && !IsSharpLeft(x - 1, y) && !IsPointBlocking(x - 1, y + 1)) { _goodMoves.Set(offset + 2, true); } if (x < _width && y < _height && IsPointGround(point) && !IsSharpRight(x + 1, y) && !IsPointBlocking(x + 1, y + 1)) { _goodMoves.Set(offset + 3, true); } if (y < _height && IsPointGround(point) && !IsPointBlocking(x, y + 1)) { _goodMoves.Set(offset + 4, true); } if (x > 0 && y > 0 && (IsPointDrop(point) || !IsPointGround(point)) && !IsSharpRight(x, y - 1) && !IsPointBlocking(x - 1, y - 1)) { _goodMoves.Set(offset + 5, true); } if (x < _width && y > 0 && (IsPointDrop(point) || !IsPointGround(point)) && !IsSharpLeft(x, y - 1) && !IsPointBlocking(x + 1, y - 1)) { _goodMoves.Set(offset + 6, true); } if (y > 0 && (IsPointDrop(point) || !IsPointGround(point)) && !IsPointBlocking(x, y - 1)) { _goodMoves.Set(offset + 7, true); } if (x > 0 && y < _height && !IsSharpLeft(x - 1, y) && !IsPointBlocking(x - 1, y + 1)) { _goodMoves.Set(offset + 8, true); } if (x < _width && y < _height && !IsSharpRight(x + 1, y) && !IsPointBlocking(x + 1, y + 1)) { _goodMoves.Set(offset + 9, true); } if (y < _height && !IsPointBlocking(x, y + 1)) { _goodMoves.Set(offset + 10, true); } if (x > 0 && y + 1 < _height && !IsSharpLeft(x - 1, y) && !IsSharpLeft(x - 1, y + 1) && !IsPointBlocking(x - 1, y + 2)) { _goodMoves.Set(offset + 14, true); } if (x < _width && y + 1 < _height && !IsSharpRight(x + 1, y) && !IsSharpRight(x + 1, y + 1) && !IsPointBlocking(x + 1, y + 2)) { _goodMoves.Set(offset + 15, true); } if (y + 1 < _height && !IsPointBlocking(x, y + 2)) { _goodMoves.Set(offset + 16, true); } if (IsPointBottom(x, y + 1)) { _goodMoves.Set(offset + 17, true); } } else { if (x > 0 && y + 1 < _height && !IsSharpLeft(x - 1, y) && !IsSharpLeft(x - 1, y + 1) && !IsPointBlocking(x - 1, y + 2)) { _goodMoves.Set(offset + 11, true); } if (x < _width && y + 1 < _height && !IsSharpRight(x + 1, y) && !IsSharpRight(x + 1, y + 1) && !IsPointBlocking(x + 1, y + 2)) { _goodMoves.Set(offset + 12, true); } if (y + 1 < _height && !IsPointBlocking(x, y + 2)) { _goodMoves.Set(offset + 13, true); } } } } }