3
\$\begingroup\$

I'm working on a menu for my poker game console app. I've conceptualized the menu(s) as a class with menu items that have their own position. I would like to get pointers on how I could improve on what I have done as I would like to add a settings menu in the future.

Here's a gif of how the menu works:

<blockquote class="imgur-embed-pub" lang="en" data-id="a/q11Is71"><a href="//imgur.com/a/q11Is71"></a></blockquote><script async src="//s.imgur.com/min/embed.js" charset="utf-8"></script>

Here's my main menu class, just so that you have an example:

    public class MainMenu
    {
        int _currentItemIndex;
        int _selectorOffset;
        IMenuItem[] _menuItems;

        public MainMenu()
        {
            _currentItemIndex = 0;
            _selectorOffset = 15;
            _menuItems = new IMenuItem[] { new StartGameItem(48, 11), new TutorialItem(48, 13), new ExitGameItem(48, 15) };
        }

        public void Open()
        {
            Console.Clear();
            GraphicsHelper.SetConsoleColor();

            bool optionSelected = false;
            Console.CursorVisible = false;
            Console.WriteLine(Resources.MainMenuContent);

            Console.CursorTop = _menuItems[_currentItemIndex].Y;
            GraphicsHelper.DrawSelector(_menuItems[_currentItemIndex].X, _selectorOffset);

            while (!optionSelected)
            {
                if (Console.KeyAvailable)
                {
                    switch (Console.ReadKey(true).Key)
                    {
                        case ConsoleKey.UpArrow:
                            GraphicsHelper.EraseSelector(_menuItems[_currentItemIndex].X, _selectorOffset);
                            _currentItemIndex--;

                            if (_currentItemIndex < 0)
                                _currentItemIndex = _menuItems.Length - 1;

                            break;

                        case ConsoleKey.DownArrow:
                            GraphicsHelper.EraseSelector(_menuItems[_currentItemIndex].X, _selectorOffset);
                            _currentItemIndex++;

                            if (_currentItemIndex > _menuItems.Length - 1)
                                _currentItemIndex = 0;

                            break;

                        case ConsoleKey.Spacebar:
                        case ConsoleKey.Enter:
                            optionSelected = true;
                            break;

                    }

                    Console.CursorTop = _menuItems[_currentItemIndex].Y;
                    GraphicsHelper.DrawSelector(_menuItems[_currentItemIndex].X, _selectorOffset);
                }
            }

            while (_currentItemIndex != -1)
            {
                _menuItems[_currentItemIndex].Select();
                Open();
            }
        }
    }

IMenu code as requested:

    public interface IMenuItem
    {
        int X { get; set; }
        int Y { get; set; }

        void Select();
    }

Graphics helper code:

    // EraseSelector is just a space in the Write method. 
    public static void DrawSelector(int x, int dx)
    {
       Console.CursorLeft = x;
       Console.Write(">");

       Console.CursorLeft = x + dx;
       Console.Write("<");

    }
    
    public static void SetConsoleColor()
    {
       Console.BackgroundColor = ConsoleColor.DarkBlue;
       Console.Clear();
       Console.ForegroundColor = ConsoleColor.Yellow;
    }

\$\endgroup\$
3
  • 1
    \$\begingroup\$ A lot of your logic seems to rely on GraphicsHelper but you don't have any code for that. Also what is in IMenuItem? \$\endgroup\$ – user33306 Aug 24 '20 at 12:19
  • \$\begingroup\$ There isn't that much code in IMenuItem as I only wanted each item to have a position and a method that executes when the item is selected or launched. The graphics helper usage in the main menu class is just responsible for changing the background and foreground colors, and drawing the "selectors" around the menu items. \$\endgroup\$ – Asel S Aug 25 '20 at 2:47
  • \$\begingroup\$ if (Console.KeyAvailable) executes billion of times per second and may cause high CPU load. Add something like Thread.Sleep(10) to the loop. \$\endgroup\$ – aepot Sep 2 '20 at 21:47

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.