Управление меню с помощью клавиш со стрелками и введите

Я пытался создать РПГ. У меня проблема с меню, где я могу выбрать класс. Я пытался создать меню, в котором вы можете управлять направлениями с помощью клавиш со стрелками к определенному классу, который затем выделяется красным цветом переднего плана, как в реальной игре, когда вы хотите что-то выбрать, вы просто используете клавиши со стрелками и вещь, на которой вы находитесь, выделяется.

Моя проблема в том, что я не могу указать расположение клавиш со стрелками, когда нажимаю клавишу со стрелкой. Я могу перейти только в первую локацию, и еще одна проблема заключается в том, что когда я выделяю класс rpg, чтобы показать пользователю, где он находится, все классы rpg получают цвет переднего плана. Я использовал Console.Read для их разделения, но теперь мне всегда приходится нажимать Enter, чтобы изменить цвет.

Вот код. Я думаю, после того, как вы откроете код, вы поймете мою проблему.

С уважением, Csharpnoob61.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Enter_Eingabe
{
    class Program
    {
        static void Main(string[] args)
        {
            //ints
            int char_HP_Current = 20;
            int char_HP_Full = 100;

            double char_Exp_Current = 10;
            double char_Exp_Full = 100;
            int char_Level_Current = 1;

            int GameOver = 0;
            int char_Move_Left_Right = 0;
            int char_Move_Up_Down = 8;

            int Error = 0;

            int Resting_Time = 0;

            int Attack_Bonus = 0;
            int Speech_Bonus = 0;
            int Sneak_Bonus = 0;
            int Armor_Bonus = 0;
            int Casting_Bonus = 0;


            //Strings

            string char_Name = "";
            string Current_Command;
            string char_Status = "";
            string char_Class;

            string test;

            Console.Clear();




            Console.SetCursorPosition(0, 8);




            do
            {
                string text = "Guardian";
                Console.SetCursorPosition(15, 8);
                Console.WriteLine(text);

                Console.SetCursorPosition(45, 8);
                Console.WriteLine("Paladin");

                Console.SetCursorPosition(30, 8);
                Console.WriteLine("Outlaw");

                ConsoleKeyInfo KeyInfo;
                KeyInfo = Console.ReadKey(true);
                switch (KeyInfo.Key)
                {
                    //Player Controlls


                    case ConsoleKey.RightArrow:
                        Console.SetCursorPosition(0, 8);
                        if (char_Move_Left_Right < 78)
                        {

                            char_Move_Left_Right+=14;
                            Console.SetCursorPosition(char_Move_Left_Right, char_Move_Up_Down);
                            Console.WriteLine("_");
                            Console.SetCursorPosition(char_Move_Left_Right - 1, char_Move_Up_Down);
                            Console.ForegroundColor = ConsoleColor.Black;
                            Console.WriteLine("_");
                            Console.ForegroundColor = ConsoleColor.White;


                        if (char_Move_Left_Right == 14)
                        {
                                if (char_Move_Up_Down == 8)
                                {                                    
                                    Console.ForegroundColor = ConsoleColor.Red;
                                    Console.SetCursorPosition(15, 8);
                                    Console.WriteLine(text);
                                    Console.Read();                                 
                                }
                                Console.ForegroundColor = ConsoleColor.White;
                            }

                        }
                        if (char_Move_Left_Right == 29)
                        {
                            if (char_Move_Up_Down == 8)
                            {
                                Console.ForegroundColor = ConsoleColor.Red;
                                Console.SetCursorPosition(30,8);
                                Console.WriteLine("Outlaw");
                                Console.Read();
                            }
                            Console.ForegroundColor = ConsoleColor.White;
                        }
                        if (char_Move_Left_Right == 44)
                        {
                            if (char_Move_Up_Down == 8)
                            {
                                Console.ForegroundColor = ConsoleColor.Red;
                                Console.SetCursorPosition(45, 8);
                                Console.WriteLine("Paladin");
                                Console.ReadLine();
                            }
                            Console.ForegroundColor = ConsoleColor.White;
                        }



                        break;
                    case ConsoleKey.LeftArrow:
                        if (char_Move_Left_Right > 1)
                        {
                            char_Move_Left_Right--;
                            Console.SetCursorPosition(char_Move_Left_Right, char_Move_Up_Down);
                            Console.WriteLine("_");
                            Console.SetCursorPosition(char_Move_Left_Right + 1, char_Move_Up_Down);
                            Console.ForegroundColor = ConsoleColor.Black;
                            Console.WriteLine("_");
                            Console.ForegroundColor = ConsoleColor.White;
                        }
                        else { }
                        break;

                    case ConsoleKey.UpArrow:
                        if (char_Move_Up_Down > 3)
                        {
                            char_Move_Up_Down--;
                            Console.SetCursorPosition(char_Move_Left_Right, char_Move_Up_Down);
                            Console.WriteLine("_");
                            Console.SetCursorPosition(char_Move_Left_Right, char_Move_Up_Down + 1);
                            Console.ForegroundColor = ConsoleColor.Black;
                            Console.WriteLine("_");
                            Console.ForegroundColor = ConsoleColor.White;
                        }
                        else { }
                        break;
                    case ConsoleKey.DownArrow:
                        if (char_Move_Up_Down < 21)
                        {
                            char_Move_Up_Down++;
                            Console.SetCursorPosition(char_Move_Left_Right, char_Move_Up_Down);
                            Console.WriteLine("_");
                            Console.SetCursorPosition(char_Move_Left_Right, char_Move_Up_Down - 1);
                            Console.ForegroundColor = ConsoleColor.Black;
                            Console.WriteLine("_");
                            Console.ForegroundColor = ConsoleColor.White;
                        }
                        else { }
                        break;
                } 
            }while (Error == 0);
        }
    }
}

person Csharpnoob61    schedule 24.10.2017    source источник
comment
Похоже, что это не будет очень многоразовым и (как вы уже столкнулись) очень подверженным ошибкам способу сделать это. Я посмотрю, если найду что-нибудь, но я рекомендую вам попробовать поместить это в функцию, чтобы вы могли использовать ее несколько раз.   -  person Manfred Radlwimmer    schedule 24.10.2017


Ответы (1)


Вместо того, чтобы писать каждую комбинацию вручную, я бы сделал следующее: использовал вспомогательный класс для общих задач, таких как действия с множественным выбором, передал набор опций и подождал, пока пользователь сделает выбор.

public class ConsoleHelper
{
    public static int MultipleChoice(bool canCancel, params string[] options)
    {
        const int startX = 15;
        const int startY = 8;
        const int optionsPerLine = 3;
        const int spacingPerLine = 14;

        int currentSelection = 0;

        ConsoleKey key;

        Console.CursorVisible = false;

        do
        {
            Console.Clear();

            for (int i = 0; i < options.Length; i++)
            {
                Console.SetCursorPosition(startX + (i % optionsPerLine) * spacingPerLine, startY + i / optionsPerLine);

                if(i == currentSelection)
                    Console.ForegroundColor = ConsoleColor.Red;

                Console.Write(options[i]);

                Console.ResetColor();
            }

            key = Console.ReadKey(true).Key;

            switch (key)
            {
                case ConsoleKey.LeftArrow:
                {
                    if (currentSelection % optionsPerLine > 0)
                        currentSelection--;
                    break;
                }
                case ConsoleKey.RightArrow:
                {
                    if (currentSelection % optionsPerLine < optionsPerLine - 1)
                        currentSelection++;
                    break;
                }
                case ConsoleKey.UpArrow:
                {
                    if (currentSelection >= optionsPerLine)
                        currentSelection -= optionsPerLine;
                    break;
                }
                case ConsoleKey.DownArrow:
                {
                    if (currentSelection + optionsPerLine < options.Length)
                        currentSelection += optionsPerLine;
                    break;
                }
                case ConsoleKey.Escape:
                {
                    if (canCancel)
                        return -1;
                    break;
                }
            }
        } while (key != ConsoleKey.Enter);

        Console.CursorVisible = true;

        return currentSelection;
    }
}

Пример выше, например, можно использовать так:

int selectedClass = ConsoleHelper.MultipleChoice(true, "Warrior", "Bard", "Mage", "Archer", 
    "Thief", "Assassin", "Cleric", "Paladin", "etc.");

selectedClass будет просто индексом выбранной опции, когда функция вернется (или -1, если пользователь нажал escape). Возможно, вы захотите добавить дополнительные параметры, такие как текст баннера («Выберите класс») или параметры форматирования.

Должно выглядеть примерно так:

Консольный вывод

Конечно, вы можете добавить дополнительные метки, такие как _these_ или > those <, чтобы еще больше выделить текущий выбор.

person Manfred Radlwimmer    schedule 24.10.2017
comment
и помните об отмене (например, нажатии Esc), если ни один из ваших вариантов не Назад: case(ConsoleKey.Escape) return -1; - person Krzysztof Skowronek; 24.10.2017
comment
Хорошая идея, добавлю. - person Manfred Radlwimmer; 24.10.2017
comment
Вы, ребята, легенды. Большое вам спасибо, надеюсь, когда-нибудь я смогу так же хорошо кодировать. - person Csharpnoob61; 24.10.2017
comment
@ Csharpnoob61 Нет проблем. Если вам нравится ответ, пожалуйста, проголосуйте и примите его, чтобы отметить этот вопрос как отвеченный (вверху слева от ответа). - person Manfred Radlwimmer; 24.10.2017
comment
Я проголосовал за него, но из-за моей низкой репутации он не будет отображаться. Где ты научился так программировать? - person Csharpnoob61; 24.10.2017
comment
@Csharpnoob61 Многолетний опыт. Программирование — это одна из тех вещей, где теория может только показать вам путь — чтобы стать лучше, нужно делать ошибки и учиться делать это лучше в следующий раз :) - person Manfred Radlwimmer; 24.10.2017
comment
Любые советы по реализации этого в Java? У меня возникли проблемы с поиском эквивалента SetCursorPosition(). - person Noam Suissa; 13.11.2020
comment
@NoamSuissa В Java это похоже на управляющий код: stackoverflow.com/questions/1001335/ - person Manfred Radlwimmer; 13.11.2020
comment
@ManfredRadlwimmer Я также нашел отличную библиотеку Java, которая содержит методы, очень похожие на методы консоли, используемые здесь: github.com/mabe02 /фонарь - person Noam Suissa; 13.11.2020