/// <summary> /// Update the graphics of the walls so adjacent wall tiles look like they are connected. /// </summary> public override void UpdateGraphicsToMatchSurroundings() { int sheetIndex = 0; int x = Location.X; int y = Location.Y; TileField tileField = Parent as TileField; if (tileField.GetTile(x, y - 1) is WallTile) sheetIndex += 1; if (tileField.GetTile(x + 1, y) is WallTile) sheetIndex += 2; if (tileField.GetTile(x, y + 1) is WallTile) sheetIndex += 4; if (tileField.GetTile(x - 1, y) is WallTile) sheetIndex += 8; sprite = new SpriteSheet(GetAssetNamesFromTileType(TileType.Wall)[0], sheetIndex); }
public LevelData(TileField tileField) { numRows = tileField.Rows; numColumns = tileField.Columns; tileData = new TileData[numColumns][]; for (int x = 0; x < numColumns; x++) { tileData[x] = new TileData[numRows]; for (int y = 0; y < numRows; y++) { tileData[x][y] = tileField.GetTile(x, y).Data; } } }
/// <summary> /// The main method of the FloodFill AI. /// </summary> /// <param name="p"> Point to start/continue the flooding from. </param> private void Flood(Point p, int keyIndex, int slidingIndex) { // If the exit has already been found or we have already visited this tile, stop the flooding. if (exitFound || visited[p.X, p.Y, keyIndex, slidingIndex]) { return; } // GuardTile is subclass of HoleTile so this will return for both. // Can't use the same for walls because DoorTile is a subclass of WallTile. // Can't use doors for which you don't have the key. if (tileField.GetTile(p) is HoleTile || tileField.GetType(p) == TileType.Wall || (tileField.GetType(p) == TileType.Door && (keyIndex & keys[(tileField.GetTile(p) as DoorTile).DoorColor]) == 0)) { return; } // The current tile has been visited. visited[p.X, p.Y, keyIndex, slidingIndex] = true; // Add the current tile to the route. route.Push(p); // If this is the exit, the algorithm is done. // Make sure this is after pushing p to route, otherwise you will stand still before the exit. if (tileField.GetType(p) == TileType.End) { exitFound = true; return; } // Check if the current tile is a keytile, // and whether we have already picked up a key of this color. if (tileField.GetType(p) == TileType.Key) { // Add the key to the keyIndex keyIndex |= keys[(tileField.GetTile(p) as KeyTile).KeyColor]; } // If we're on an ice tile, we need the sliding direction to see if we can change direction. if (tileField.GetType(p) == TileType.Ice) { // Retrieve the current and previous point in the route. Point current = route.Pop(); Point previous = route.Pop(); // Calculate the direction you're moving at. slidingDirection = current - previous; // Return the current and previous point to the route. route.Push(previous); route.Push(current); } //If you can move onto the tile behind the ice tile, you can't change direction if (tileField.GetType(p) == TileType.Ice && !(tileField.GetTile(p.X + slidingDirection.X, p.Y + slidingDirection.Y) is WallTile)) { //Only keep going in this direction Flood(p + slidingDirection, keyIndex, slides[GetDirectionFromPoint(slidingDirection)]); } // Otherwise we can move in all directions. else { PlayerAction[] action = getActionsInRandomOrder(); for (int i = 0; i < 5; i++) { if (action[i] == PlayerAction.SPECIAL && tileField.GetType(p) == TileType.Portal) { Flood((tileField.GetTile(p) as PortalTile).Destination, keyIndex, 0); } else if (action[i].IsDirection()) { // Obstacles are checked earlier in Flood() so we only need to check whether the new point is in the tilefield. if (!tileField.OutOfTileField(p + action[i].ToDirection().ToPoint())) { Flood(p + action[i].ToDirection().ToPoint(), keyIndex, 0); } } } } // All directions are done, return to the previous point. // If the exit has been found, keep the route intact. if (!exitFound && route.Count > 0) { route.Pop(); } }