public static bool[,] GenerateMazeTile(MazeTileType tileType, bool includeCenter) { var tile = new bool[3, 3]; // Corners tile[0, 0] = true; tile[0, 2] = true; tile[2, 0] = true; tile[2, 2] = true; if (includeCenter && tileType == MazeTileType.None) { tile[1, 1] = true; } if (!tileType.HasFlag(MazeTileType.North)) { tile[1, 0] = true; } if (!tileType.HasFlag(MazeTileType.East)) { tile[2, 1] = true; } if (!tileType.HasFlag(MazeTileType.South)) { tile[1, 2] = true; } if (!tileType.HasFlag(MazeTileType.West)) { tile[0, 1] = true; } return(tile); }
public static MapTile GetTile(MazeTileType mazeTileType) { return(mazeTileType switch { MazeTileType.None => new MazeTile(), MazeTileType.Start => new StartTile(), MazeTileType.Finish => new FinishTile(), MazeTileType.Player => new PlayerTile(), MazeTileType.Wall => new WallTile(), _ => throw new Exception() });
private MazeTileType GenerateCompatibleTileType(MazeTileType tileType) { var resultTile = tileType; if (Random.NextDouble() > 0.7) { resultTile |= MazeTileType.East; } if (Random.NextDouble() > 0.7) { resultTile |= MazeTileType.South; } return(resultTile); }
private MazeTileType[] GenerateTilesRow(out MazeTileType[] path) { var rowTiles = new MazeTileType[TilesInRow]; rowTiles[LastTilePassIndex] |= MazeTileType.North; var direction = GenerateRandomDirection(); var length = Random.Next(1, TilesInRow); var newTilePassIndex = Math.Abs((LastTilePassIndex + direction * length) % (TilesInRow)); rowTiles[newTilePassIndex] |= MazeTileType.South; var fromIndex = Math.Min(LastTilePassIndex, newTilePassIndex); var toIndex = Math.Max(LastTilePassIndex, newTilePassIndex); for (int i = fromIndex; i < toIndex; i++) { rowTiles[i] |= MazeTileType.East; rowTiles[i + 1] |= MazeTileType.West; } path = new MazeTileType[TilesInRow]; rowTiles.CopyTo(path, 0); LastTilePassIndex = newTilePassIndex; for (int i = 0; i < rowTiles.Length; i++) { var top = LastRowTiles[i].HasFlag(MazeTileType.South) ? MazeTileType.North : default; MazeTileType left = default; if (i > 0) { left = LastRowTiles[i - 1].HasFlag(MazeTileType.East) ? MazeTileType.West : default; } rowTiles[i] = GenerateCompatibleTileType(rowTiles[i] | top | left); } return(rowTiles); }
/// <summary> /// Sets some default values /// </summary> private void SetupMazeEditor(ScreenBuffer screenBuffer) { // maze properties _mazeOffsetX = 1; _mazeOffsetY = 6; // cursor properties _cursorEnabled = true; _cursorX = _mazeOffsetX; _cursorY = _mazeOffsetY; _cursorSpeed = 1; _cursorDirection = Direction.Down; // trigger updates _mazeUpdated = true; // minX, maxX, minY, maxY _cursorBoundaries = new Tuple <int, int, int, int>(_mazeOffsetX, screenBuffer.BufferWidth - 2, _mazeOffsetY, screenBuffer.BufferHeight - 2); // map a direction to a set of delta x,y values _cursorDirectionDeltaMap = new Dictionary <Direction, Tuple <int, int> >() { { Direction.Down, new Tuple <int, int>(0, 1) }, { Direction.Left, new Tuple <int, int>(-1, 0) }, { Direction.Right, new Tuple <int, int>(1, 0) }, { Direction.Up, new Tuple <int, int>(0, -1) } }; // pre-calculate ui outline strings const int uiTopSplitA = 72; const int uiTopSplitB = 80; _uiOutline = new string[screenBuffer.BufferHeight]; string uiLineTop = $"{Character.TopLeft}{Utils.Repeat(Character.Horizontal, uiTopSplitA)}{Character.TopCentre}{Utils.Repeat(Character.Horizontal, screenBuffer.BufferWidth - uiTopSplitA - uiTopSplitB - 4)}{Character.TopCentre}{Utils.Repeat(Character.Horizontal, uiTopSplitB)}{Character.TopRight}"; string uiLineTopMiddle = $"{Character.Vertical}{Utils.Repeat(" ", uiTopSplitA)}{Character.Vertical}{Utils.Repeat(" ", screenBuffer.BufferWidth - uiTopSplitA - uiTopSplitB - 4)}{Character.Vertical}{Utils.Repeat(" ", uiTopSplitB)}{Character.Vertical}"; string uiLineTopSplit = $"{Character.MiddleLeft}{Utils.Repeat(Character.Horizontal, uiTopSplitA)}{Character.BottomCentre}{Utils.Repeat(Character.Horizontal, screenBuffer.BufferWidth - uiTopSplitA - uiTopSplitB - 4)}{Character.BottomCentre}{Utils.Repeat(Character.Horizontal, uiTopSplitB)}{Character.MiddleRight}"; string uiLineMiddle = $"{Character.Vertical}{Utils.Repeat(" ", screenBuffer.BufferWidth - 2)}{Character.Vertical}"; string uiLineBottom = $"{Character.BottomLeft}{Utils.Repeat(Character.Horizontal, screenBuffer.BufferWidth - 2)}{Character.BottomRight}"; // draw screen outline for (var y = 0; y < screenBuffer.BufferHeight; y++) { switch (y) { case 0: _uiOutline[y] = uiLineTop; break; case 1: case 2: case 3: case 4: _uiOutline[y] = uiLineTopMiddle; break; case 5: _uiOutline[y] = uiLineTopSplit; break; default: _uiOutline[y] = y == screenBuffer.BufferHeight - 1 ? uiLineBottom : uiLineMiddle; break; } } // create the pixel styles _cursorPixel = new Pixel(Character.MediumBlock, Style.ForegroundColor.Cyan, Style.BackgroundColor.Grayscale235); _blankMapPixel = new Pixel(Style.ForegroundColor.White, Style.BackgroundColor.Grayscale235); // set the current pixel _currentTileTool = MazeTileType.None; // get the background colours _isBackgroundColourSelector = true; _currentBackgroundColour = 0; _currentForegroundColour = 0; _backgroundColours = typeof(Style.BackgroundColor).GetFields().Select(fi => fi.GetValue(fi)?.ToString()).ToArray(); _foregroundColours = typeof(Style.ForegroundColor).GetFields().Select(fi => fi.GetValue(fi)?.ToString()).ToArray(); /* * Setup menus */ // file menu _fileMenu = new Menu("File Menu"); _fileMenu.AddItem("Save", (sb) => { _maze.Save(); _fileMenu.Enabled = false; }); _fileMenu.AddItem("Rename"); _fileMenu.AddItem("Close File Menu", (sb) => _fileMenu.Enabled = false); _fileMenu.AddItem("Exit to main menu", (sb) => { new MazeGame().Start(); /* basically a hacky way to restart */ }); // edit menu _editMenu = new Menu("Edit Menu"); _editMenu.AddItem("Eraser Tool", (sb) => { _currentTileTool = MazeTileType.None; _editMenu.Enabled = false; }); _editMenu.AddItem("Wall Tool", (sb) => { _currentTileTool = MazeTileType.Wall; _editMenu.Enabled = false; }); _editMenu.AddItem("Start Tool", (sb) => { _currentTileTool = MazeTileType.Start; _editMenu.Enabled = false; }); _editMenu.AddItem("Finish Tool", (sb) => { _currentTileTool = MazeTileType.Finish; _editMenu.Enabled = false; }); _editMenu.AddItem("Player Spawn Tool", (sb) => { _currentTileTool = MazeTileType.Player; _editMenu.Enabled = false; }); _editMenu.AddItem("Close Edit Menu", (sb) => _editMenu.Enabled = false); // debug menu _debugMenu = new Menu("Debug Menu"); _debugMenu.AddItem("Shrink maze size", (sb) => { _maze.ResizeMaze(); // force the maze to be drawn _mazeUpdated = true; DrawMaze(screenBuffer); _debugMenu.Enabled = false; // close the menu after execution }); _debugMenu.AddItem("Toggle cursor", (sb) => { _cursorEnabled = !_cursorEnabled; _debugMenu.Enabled = false; }); _debugMenu.AddItem("Close Debug Menu", (sb) => _debugMenu.Enabled = false); }
/// <summary> /// Display the maze along with the editor UI and handle all of the User Inputs /// </summary> /// <param name="screenBuffer"></param> public void Show(ScreenBuffer screenBuffer) { _isEditorRunning = true; SetupMazeEditor(screenBuffer); // add the ui border as a constant render screenBuffer.AddConstantRender(0, 0, _uiOutline); while (_isEditorRunning) { // we shouldn't need to check whether we need to update as this loop will only continue // on user input Draw(screenBuffer); // read input var consoleKeyInfo = Console.ReadKey(true); var consoleKey = consoleKeyInfo.Key; // ReSharper disable once SwitchStatementMissingSomeEnumCasesNoDefault switch (consoleKey) { /* * Cursor Movement */ case ConsoleKey.UpArrow: // only move if cursor enabled if (!_cursorEnabled) { break; } MoveCursor(0, -1); _cursorDirection = Direction.Up; break; case ConsoleKey.DownArrow: // only move if cursor enabled if (!_cursorEnabled) { break; } MoveCursor(0, 1); _cursorDirection = Direction.Down; break; case ConsoleKey.LeftArrow: // only move if cursor enabled if (!_cursorEnabled) { break; } MoveCursor(-1, 0); _cursorDirection = Direction.Left; break; case ConsoleKey.RightArrow: // only move if cursor enabled if (!_cursorEnabled) { break; } MoveCursor(1, 0); _cursorDirection = Direction.Right; break; /* * Cursor Speed */ case ConsoleKey.Add: ModifyCursorSpeed(+1); break; case ConsoleKey.Subtract: ModifyCursorSpeed(-1); break; /* * Draw a Map tile */ case ConsoleKey.Spacebar: // only draw if the cursor is enabled if (!_cursorEnabled) { break; } DrawTile(); break; /* * Map Tile Selection */ case ConsoleKey.D1: _currentTileTool = MazeTileType.None; break; case ConsoleKey.D2: _currentTileTool = MazeTileType.Wall; break; case ConsoleKey.D3: _currentTileTool = MazeTileType.Start; break; case ConsoleKey.D4: _currentTileTool = MazeTileType.Finish; break; case ConsoleKey.D5: _currentTileTool = MazeTileType.Player; break; /* * Colour selector */ case ConsoleKey.Tab: CycleColourSelector(); break; case ConsoleKey.Oem8: _isBackgroundColourSelector = !_isBackgroundColourSelector; break; /* * Menus */ // File menu case ConsoleKey.F1: _fileMenu.Show(screenBuffer); break; // Edit menu case ConsoleKey.F2: _editMenu.Show(screenBuffer); break; // Debug Menu case ConsoleKey.F3: _debugMenu.Show(screenBuffer); break; } // clear any other input // NOTE: This isn't ideal but this prevents a queue of keys to be read // if the user holds down a key which would cause "input lag" of // considerable effect. while (Console.KeyAvailable) { Console.ReadKey(true); } } }
private void Awake() { _mazeTileType = (MazeTileType)Enum.Parse(typeof(MazeTileType), gameObject.tag); OnPlayerInteract.AddListener(ConsumePellet); }
private void BuildMaze(Vector2 tilePosition, MazeTileType tileType) { GameObject tilePrefab; Transform tileParent; switch (tileType) { case MazeTileType.Wall: tilePrefab = WallPrefab; tileParent = WallsParent.transform; break; case MazeTileType.Pellet: tilePrefab = PelletPrefab; tileParent = PelletsParent.transform; break; case MazeTileType.Energizer: tilePrefab = EnergizerPrefab; tileParent = EnergizersParent.transform; break; case MazeTileType.Intersection: tilePrefab = IntersectionPrefab; tileParent = IntersectionsParent.transform; break; case MazeTileType.OutOfBound: tilePrefab = OutOfBoundPrefab; tileParent = OutOfBoundsParent.transform; break; case MazeTileType.Empty: tilePrefab = EmptyPrefab; tileParent = EmptiesParent.transform; break; case MazeTileType.GhostHouse: tilePrefab = GhostHousePrefab; tileParent = GhostHouseParent.transform; break; case MazeTileType.Tunnel: tilePrefab = TunnelPrefab; tileParent = TunnelsParent.transform; break; case MazeTileType.Fruit: tilePrefab = FruitPrefab; tileParent = FruitParent.transform; break; default: throw new ArgumentOutOfRangeException(nameof(tileType), tileType, null); } var newItem = Instantiate(tilePrefab, tileParent, false); newItem.transform.localPosition = new Vector3(tilePosition.x, tilePosition.y, 0); var newTile = newItem.GetComponent <MazeTile>(); newTile.SetTilePosition(tilePosition.x, tilePosition.y); newTile.SetTilePosition(tilePosition.x, tilePosition.y); }
public MazeGenerator(int tilesCount) { TilesInRow = tilesCount; LastRowTiles = new MazeTileType[TilesInRow]; Random = new Random(); }