Как стать автором
Обновить

Как сделать красивый вывод текста на C#

Время на прочтение5 мин
Количество просмотров12K

Пролог

Прошлый пост на счет сердечка посмотрело много людей и у меня возникла идея сделать еще одну простенькую, но достаточно красивую штуку, а именно такой вот вывод текста(можно сказать анимированного, но язык не поворачивается). Данный пост подходит для новичков, можно потренироваться в использовании массивов, циклов, немного классов и методов.

Экспозиция 

Создаем класс "Print", и в нем создаем приватный метод "Letter" - который возращает массив с "box" буквами, их можно взять из моего кода(который ниже), или найти в интернете.

private static string[,] Letter()
{
  string[,] letter = new string[,]
  {
    {
      //letter with index 0
      "    ",
      "    ",
      "    ",
      "    ",
      "    ",
      "    ",
    },
    {
      //letter with index 1
      "╔══╗",
      "║╔╗║",
      "║╚╝║",
      "║╔╗║",
      "║║║║",
      "╚╝╚╝",
    },
    {
      //letter with index 2
      "╔═══╗",
      "║╔══╝",
      "║╚══╗",
      "║╔═╗║",
      "║╚═╝║",
      "╚═══╝",
    },
    {
      //letter with index 3
      "╔══╗ ",
      "║╔╗║ ",
      "║╚╝╚╗",
      "║╔═╗║",
      "║╚═╝║",
      "╚═══╝",
    },
    {
      //letter with index 4
      "╔══╗",
      "║╔═╝",
      "║║  ",
      "║║  ",
      "║║  ",
      "╚╝  ",
    },
    {
      //letter with index 5
      " ╔══╗ ",
      " ║╔╗║ ",
      " ║║║║ ",
      " ║║║║ ",
      "╔╝╚╝╚╗",
      "╚════╝",
    },
    {
      //letter with index 6
      "╔═══╗",
      "║╔══╝",
      "║╚══╗",
      "║╔══╝",
      "║╚══╗",
      "╚═══╝",
    },
    {
      //letter with index 7
      "╔╩═╩╗",
      "║╔══╝",
      "║╚══╗",
      "║╔══╝",
      "║╚══╗",
      "╚═══╝",
    },
    {
      //letter with index 8
      "╔╗╔╗╔╗",
      "║║║║║║",
      "║╚╝╚╝║",
      "║╔╗╔╗║",
      "║║║║║║",
      "╚╝╚╝╚╝",
    },
    {
      //letter with index 9
      "╔═══╗",
      "╚══╗║",
      " ╔═╝║",
      " ╚═╗║",
      "╔══╝║",
      "╚═══╝",
    },
    {
      //letter with index 10
      "╔╗╔╗",
      "║║║║",
      "║║║║",
      "║║╔║",
      "║╚╝║",
      "╚══╝",
    },
    {
      //letter with index 11
      "╔╗╩╔╗",
      "║║ ║║",
      "║║ ║║",
      "║║ ╔║",
      "║╚═╝║",
      "╚═══╝",
    },
    {
      //letter with index 12
      "╔╗╔══╗",
      "║║║╔═╝",
      "║╚╝║  ",
      "║╔╗║  ",
      "║║║╚═╗",
      "╚╝╚══╝",
    },
    {
      //letter with index 13
      " ╔══╗",
      " ║╔╗║",
      " ║║║║",
      " ║║║║",
      "╔╝║║║",
      "╚═╝╚╝",
    },
    {
      //letter with index 14
      "╔╗  ╔╗",
      "║║  ║║",
      "║╚╗╔╝║",
      "║╔╗╔╗║",
      "║║╚╝║║",
      "╚╝  ╚╝",
    },
    {
      //letter with index 15
      "╔╗╔╗",
      "║║║║",
      "║╚╝║",
      "║╔╗║",
      "║║║║",
      "╚╝╚╝",
    },
    {
      //letter with index 16
      "╔══╗",
      "║╔╗║",
      "║║║║",
      "║║║║",
      "║╚╝║",
      "╚══╝",
    },
    {
      //letter with index 17
      "╔══╗",
      "║╔╗║",
      "║║║║",
      "║║║║",
      "║║║║",
      "╚╝╚╝",
    },
    {
      //letter with index 18
      "╔═══╗",
      "║╔═╗║",
      "║╚═╝║",
      "║╔══╝",
      "║║   ",
      "╚╝   ",
    },
    {
      //letter with index 19
      "╔══╗",
      "║╔═╝",
      "║║  ",
      "║║  ",
      "║╚═╗",
      "╚══╝",
    },
    {
      //letter with index 20
      "╔════╗",
      "╚═╗╔═╝",
      "  ║║  ",
      "  ║║  ",
      "  ║║  ",
      "  ╚╝  ",
    },
    {
      //letter with index 21
      "╔╗╔╗",
      "║║║║",
      "║╚╝║",
      "╚═╗║",
      " ╔╝║",
      " ╚═╝",
    },
    {
      //letter with index 22
      "╔═════╗",
      "║ ╔╦╗ ║",
      "║ ║║║ ║",
      "║ ╚╩╝ ║",
      "╚═╗ ╔═╝",
      "  ╚═╝  ",
    },
    {
      //letter with index 23
      "╔══╗╔══╗",
      "╚═╗║║╔═╝",
      "  ║╚╝║  ",
      "  ║╔╗║  ",
      "╔═╝║║╚═╗",
      "╚══╝╚══╝",
    },
    {
      //letter with index 24
      "╔╗╔╗",
      "║║║║",
      "║║║║",
      "║║║║",
      "║╚╝║",
      "╚══╗",
    },
    {
      //letter with index 25
      "╔╗╔╗",
      "║║║║",
      "║╚╝║",
      "╚═╗║",
      "  ║║",
      "  ╚╝",
    },
    {
      //letter with index 26
      "╔╗╔╗╔╗",
      "║║║║║║",
      "║║║║║║",
      "║║║║║║",
      "║╚╝╚╝║",
      "╚════╝",
    },
    {
      //letter with index 27
      "╔╗╔╗╔╗",
      "║║║║║║",
      "║║║║║║",
      "║║║║║║",
      "║╚╝╚╝║",
      "╚════╗",
    },
    {
      //letter with index 28
      "═╗   ",
      "╗║   ",
      "║╚══╗",
      "║╔═╗║",
      "║╚═╝║",
      "╚═══╝",
    },
    {
      //letter with index 29
      "╔╗  ╔╗",
      "║║  ║║",
      "║╚══╣║",
      "║╔═╗║║",
      "║╚═╝║║",
      "╚═══╩╝",
    },
    {
      //letter with index 30
      "╔╗   ",
      "║║   ",
      "║╚══╗",
      "║╔═╗║",
      "║╚═╝║",
      "╚═══╝",
    },
    {
      //letter with index 31
      "╔═══╗",
      "╚══╗║",
      " ╔═╝╝",
      " ╚═╗╗",
      "╔══╝║",
      "╚═══╝",
    },
    {
      //letter with index 32
      "╔╗╔══╗",
      "║║║╔╗║",
      "║╚╝║║║",
      "║╔╗║║║",
      "║║║╚╝║",
      "╚╝╚══╝",
    },
    {
      //letter with index 33
      "╔═══╗",
      "║╔═╗║",
      "║╚═╝║",
      "╚╗╔╗║",
      " ║║║║",
      " ╚╝╚╝",
    },
    {
      //letter with index 34
      " ╔╗",
      "╔╝║",
      "╚╗║",
      " ║║",
      " ║║",
      " ╚╝",
    },
    {
      //letter with index 35
      "╔══╗",
      "╚═╗║",
      "╔═╝║",
      "║╔═╝",
      "║╚═╗",
      "╚══╝",
    },
    {
      //letter with index 36
      "╔══╗",
      "╚═╗║",
      "╔═╝║",
      "╚═╗║",
      "╔═╝║",
      "╚══╝",
    },
    {
      //letter with index 37
      "╔╗╔╗",
      "║║║║",
      "║╚╝║",
      "╚═╗║",
      "  ║║",
      "  ╚╝",
    },
    {
      //letter with index 38
      "╔══╗",
      "║╔═╝",
      "║╚═╗",
      "╚═╗║",
      "╔═╝║",
      "╚══╝",
    },
    {
      //letter with index 39
      "╔══╗",
      "║╔═╝",
      "║╚═╗",
      "║╔╗║",
      "║╚╝║",
      "╚══╝",
    },
    {
      //letter with index 40
      "╔══╗",
      "╚═╗║",
      "  ║║",
      "  ║║",
      "  ║║",
      "  ╚╝",
    },
    {
      //letter with index 41
      "╔══╗",
      "║╔╗║",
      "║╚╝║",
      "║╔╗║",
      "║╚╝║",
      "╚══╝",
    },
    {
      //letter with index 42
      "╔══╗",
      "║╔╗║",
      "║╚╝║",
      "╚═╗║",
      "╔═╝║",
      "╚══╝",
    },
    {
      //letter with index 43
      "╔══╗",
      "║╔╗║",
      "║║║║",
      "║║║║",
      "║╚╝║",
      "╚══╝",
    },
    {
      //letter with index 44
      "  ",
      "  ",
      "  ",
      "  ",
      "╔╗",
      "╚╣",
    },
    {
      //letter with index 45
      "  ",
      "  ",
      "  ",
      "  ",
      "╔╗",
      "╚╝",
    },
    {
      //letter with index 46
      "╔╗",
      "║║",
      "║║",
      "╚╝",
      "╔╗",
      "╚╝",
    },
    {
      //letter with index 47
      "╔═╗",
      "╚╗║",
      "╔╝║",
      "║╔╝",
      "╔╗ ",
      "╚╝ ",
    },
    {
      //letter with index 48
      "  ",
      "╔╗",
      "╚╝",
      "╔╗",
      "╚╝",
      "  ",
    },
    {
      //letter with index 49
      "╔═╗",
      "╚╗║",
      " ║║",
      " ║║",
      "╔╝║",
      "╚═╝",
    },
    {
      //letter with index 50
      "╔═╗",
      "║╔╝",
      "║║ ",
      "║║ ",
      "║╚╗",
      "╚═╝",
    },
    {
      //letter with index 51
      "    ",
      "    ",
      "╔══╗",
      "╚══╝",
      "    ",
      "    ",
    },
    {
      //letter with index 52
      "              ",
      " ▄█▀█▄  ▄███▄ ",
      "▐█░██████████▌",
      " ██▒█████████ ",
      "  ▀████████▀  ",
      "     ▀██▀     ",
    },
    {
      //letter with index 53
      "###",
      "@@@",
      "###",
      "@@@",
      "###",
      "@@@",
    },
  };

  return letter;
}

Завязка

В классе "Print" создаем еще один метод, который будет записывать в массив(буфер) и выводить "box" текст на экран.

public static void Phrase(string phrase) //В МЕТОД ВПИСЫВАЕТ СТРОКА
{
  //ОБЪЯВЛЯЕМ МАССИВЫ
  char[] arrPhrase = phrase.ToCharArray(); //РАЗБИВАЕМ ФРАЗУ НА CHAR ЭЛЕМЕНТЫ
  char[] arrSymbol = new char[] { ' ', 'А', 'Б', 'В', 'Г', 'Д', 'Е', 'Ё', 'Ж', 'З', 'И', 'Й', 'К', 'Л', 'М', 'Н', 'О', 'П', 'Р', 'С', 'Т', 'У', 'Ф', 'Х', 'Ц', 'Ч', 'Ш', 'Щ', 'Ъ', 'Ы', 'Ь', 'Э', 'Ю', 'Я', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', ',', '.', '!', '?', ':', ')', '(', '-', '♥' } //СИМВОЛЫ КОТОРЫЕ МЫ БУДЕМ СРАВНИВАТЬ С СИМВОЛОЛАМИ  arrPhrase SE//
  string[,] arrLetter = Letter(); //БЕРЕМ МАССИВ С "BOX" БУКВАМИ
  string[,] buffer = new string[arrLetter.GetLength(1), arrPhrase.Length]; //БУФЕР КОТОРЫЙ БУДЕТ В СЕБЕ ХРАНИТЬ БУКВЫ, ВЫСОТА У НЕГО ЭТО КОЛ-ВО РЯДКОВ У "BOX" БУКВЫ, У ВСЕХ БУКВ ВЫСОТА 6 РЯДКОВ, А ШИРИНА У НЕГО ЭТО КОЛИЧЕСТВО БУКВ В ФРАЗЕ

  //ПОСКОЛЬКУ СИМВОЛОВ ВРЯД-ЛИ БУДЕТ > 255, ТО ДЛЯ ТОГО, ЧТОБ ЭКНОМИТЬ ОЗУ МЫ БУДЕМ БРАТЬ ТИП ДАННЫХ BYTE, ПОЭТОМУ ДЕЛАЛ ПРОВЕРКУ, ЧТОБ ЭЛЕМЕНТОВ НЕ БЫЛО > 255
  if (arrPhrase.Length > 255)
  {
    Console.WriteLine($"ERROR: the number of characters is more than {255}");
  }

  //ЦИКЛ КОТОРЫЙ ДЕЛАЕТ ПРОВЕРКУ ЭЛЕМЕНТОВ И ЗАПИСЫВАЕТ В БУФЕР ЭЛЕМЕНТЫ
  for (byte i = 0; i < arrPhrase.Length; i++) //ТИП BYTE ОПЯТЬ ЖЕ, ЧТОБ ЭКОНОМИТЬ ПАМЯТЬ
  { //САМ ЦИКЛ ПРОСТО ПЕРЕБИРАЕТ КАЖДЫЙ CHAR ЭЛЕМЕНТ СТРОКИ, КОТОРУЮ ПИШЕМ В МЕТОД
    byte index = 0; //ЭТО НАМ НУЖНО БУДЕТ, ЧТОБ В БУФЕР ЗАПИСАТЬ "BOX" БУКВУ С ОПРЕДЕЛЕННЫМ ИНДЕКСОМ, КАЖДЫЙ ИНДЕКС УКАЗАН В КОММЕНТАРИЯХ В САМОМ МАССИВЕ С ЭТИМИ БУКВАМИ, ЧТОБ НЕ ЗАПУТАТЬСЯ

    for (byte k = 0; k < arrSymbol.Length; k++) //ТУТ МЫ ПРОСТО ПЕРЕБИРАЕМ КАЖДЫЙ ЭЛЕМЕНТ ИЗ МАССИВА С СИМВОЛАМИ КОТОРЫЙ МЫ ПИСАЛИ РАНЕЕ
    {
      if (arrPhrase[i] == arrSymbol[k]) { index = k; break; } //СРАВНИВАЕМ CHAR ЭЛЕМЕНТ СТРОКИ С CHAR ЭЛЕМЕНТОМ МАССИВА С СИМВОЛАМИ, ЕСЛИ СОВПАЛО, ТО МЫ НАЗНАЧАЕМ НУЖНЫЙ ИНДЕКС И ВЫХОДИМ ИЗ ЦИКЛА, ДАБЫ ДАЛЬШЕ НЕ ТРАТИТЬ РЕСУРСЫ ПК НА ПРОВЕРКУ
      else index = 53; //ЕСЛИ НЕ БЫЛО СОВПАДЕНИЯ, ТО МЫ НАЗНАЧЕМ INDEX, КОТОРЫЙ СООТВЕТВУЕТ "BOX" БУКВЕ С # И @ (ТИП ОШИБКА)
    }
		
    //ЗАПИСЫВАЕМ В БУФЕР "BOX" БУКВЫ
    for (byte j = 0; j < arrLetter.GetLength(1); j++)
    {
      buffer[j, i] = arrLetter[index, j]; //ЗАПИСУЕМ ПО-СТРОЧНО БУКВЫ В БУФФЕР
    }
  }

  //ВЫВОД МАССИВА
  for (byte i = 0; i < arrLetter.GetLength(1); i++) //ВЫСОТА БУФЕРА ЭТО КОЛ-ВО РЯДКОВ В БУКВЕ
  {
    for (byte j = 0; j < arrPhrase.Length; j++) //ШИРИНА БУФЕРА КОЛ-ВО БУКВ В ФРАЗЕ
    {
      Console.Write(buffer[i, j]);
    }
    Console.WriteLine();
  }
}

Развитие действия

Дабы сделать "анимацию" нам просто надо стирать предыдущую строку с задержкой, чтоб вывелась новая. Для этого опять таки в классе "Print" создаем метод "Clear", который с задержкой стирает консоль.

public static void Clear(double second)
{
  Thread.Sleep(TimeSpan.FromSeconds(second)); //ПК "СПИТ" НАЗНАЧЕННОЕ КОЛ-ВО СЕКУНД
  Console.Clear(); //ОЧИЩЕНИЕ КОНСОЛИ
}

СЕЙЧАС СТРУКТУРА КЛАССА "PRINT" ВЫГЛЯДИТ ТАК:

Кульминация

Пробуем в Main вывести наше чудо.
Делаем простенький цикл, который будет работать как секундомер

Нажимаем f5 и скрещиваем пальчики)

не успел запись включить, но все работает
не успел запись включить, но все работает

Развязка

Теперь, пишем вывод, который был на гифке в начале моего поста

Print.Phrase("ПРИВЕТ, ХАБР");
Print.Clear(1.5);
Print.Phrase("КАК");
Thread.Sleep(TimeSpan.FromSeconds(.5));
Print.Phrase("У ТЕБЯ");
Thread.Sleep(TimeSpan.FromSeconds(.5));
Print.Phrase("ДЕЛА?");
Print.Clear(2);
Print.Phrase("У МЕНЯ ХОРОШО");
Print.Phrase(":)");
Print.Clear(1.5);
Print.Phrase("СПАСИБО");
Print.Clear(.5);
Print.Phrase("ВАМ");
Print.Clear(.5);
Print.Phrase("ЗА");
Print.Clear(.5);
Print.Phrase("АКТИВНОСТЬ");
Print.Clear(1.5);
Print.Phrase("ЛЮБЛЮ ВАС");
Print.Clear(1.5);
Console.ForegroundColor = ConsoleColor.Red;
Print.Phrase("♥");
Print.Clear(1.5);

Эпилог

Достаточно простенькое, но забавное приложение, которое скорее всего соберет меньше просмотров чем предыдущее сердечко, но над этим постом я старался больше). В любом случае спасибо всем кто просмотрит и прокомментирует, а тем более если найдут ошибки, или облегчат/улучшат код.

Теги:
Хабы:
+5
Комментарии4

Публикации

Истории

Работа

Ближайшие события

Weekend Offer в AliExpress
Дата20 – 21 апреля
Время10:00 – 20:00
Место
Онлайн
Конференция «Я.Железо»
Дата18 мая
Время14:00 – 23:59
Место
МоскваОнлайн