• Программинг

Нужны источники бесперебойного питания?

Источники бесперебойного питания от дизельстор

C#. Использование System.Console для создания игр в текстовом режиме. Часть 2

Специальные символы

Посмотрите еще раз на скриншот из Snipes. Вы обратили внимание, какие линии, кружочки, треугольники, прямоугольники и улыбающиеся лица? Это ведь не буквы и цифры! Как же так?

Давайте проведем эксперимент. Если вы уже открыли окно командной строки, откройте меню Windows, кликнув мышкой на значок «c:\» в верхнем левом углу и выберите «Свойства». Вы увидите, что командная строка обычно использует шрифт Lucida Console. Откройте таблицу символов «Пуск >> Выполнить >> charmap.exe» (Start >> Run >> charmap.exe) и выберите из списка шрифтов шрифт Lucida Console. Прокрутите список символов до греческих букв и сделайте двойной щелчок по одной из них (например, по символу зета Θ), таким образом, этот символ появится в текстовом поле «Для копирования». Далее прокрутите список до кириллических символов и выполните двойной щелчок на одном из них (например, на Ж). Нажмите кнопку «Копировать» для копирования текста в буфер обмена. Теперь вернитесь в командную строку, снова откройте меню и выберите «Изменить >> Вставить» (Edit >> Paste). Обратите внимание что получилось:

Символ зета вставился правильно, но вместо буквы «Ж», вставился знак вопроса (прим. переводчика: это актуально только для машин без настройки кириллицы). Это происходит, потому что консоль MS-DOS и все его потомки, могут отображать только 250 символов. Так как, изначально использовалась кодировка ASCII, которая содержит 255 символов, 250 из которых видимые и плюс 6 непечатаемых: сигнал, горизонтальное табулирование, null, возврат на один символ, перевод строки и перевод каретки. Сейчас они представлены в кодировке Unicode 437. Если вы являетесь читателем Head First C#, вы можете узнать из 9-ой главы, как использовать Unicode. Но если нет, не волнуйтесь – все, что нужно знать это то, что вы можете преобразовывать значение байт (от 0 до 255) в символы MS-DOS ASCII.

1 // Преобразование массива байт в символы MS-DOS
2 char[] charArray = Encoding.GetEncoding(437).GetChars(byteArray);

Следующая программа показывает, как вывести на печать таблицу MS-DOS ASCII, которая еще в 80-х и начале 90-х печаталась на внутренней стороне обложки большинства книг по программированию. К счастью, теперь, вы можете просто скопировать и вставить символы прямо в командную строку. (Попробуйте включить опцию быстрой вставки в окне командной строки, которую можно найти в свойствах окна. Это позволит вам выделять, копировать, вставлять текст и перетаскивать его с помощью мыши.)

CodePage437.cs:

1 using System;
2 using System.Text;
3  
4 class CodePage437
5 {
6      public static void Main(string[] args)
7      {
8           // Задаем заголовок окна
9           Console.Title = "Кодировка 437: MS-DOS ASCII";
10  
11           for (byte b = 0; b < byte.MaxValue; b++)
12           {
13                char c = Encoding.GetEncoding(437).GetChars(new byte[] {b})[0];
14                switch (b)
15                {
16                     case 8: // Backspace
17                     case 9: // Tab
18                     case 10: // Перевод строки
19                     case 13: // Возврат каретки
20                         c = '.';
21                         break;
22                 }
23  
24                Console.Write("{0:000} {1}   ", b, c);
25  
26                // 7 это сигнал -- Console.Beep() работает также
27                if (b == 7) Console.Write(" ");
28  
29                if ((b + 1) % 8 == 0)
30                    Console.WriteLine();
31            }
32           Console.WriteLine();
33       }
34 }

Результат вы можете увидеть на скриншоте ниже. Обратите особое внимание на символы 176, 177 и 178. Их особенность полезна для рисования текстовой графики в сочетании с цветами переднего и заднего фона. Таким образом можно достичь некоторых эффектов сглаживания. Вы можете увидеть пример сглаживание при использовании этих символов, если внимательно посмотрите на следующий скриншот:

32

Половинные блоки символов (с 219 по 223) также полезны, особенно если вы используете цвета текста и фона. Они позволяют сделать сложные тени трубопроводов и шахматный порядок.

Есть еще одна вещь, о которой вы должны знать касательно этих символов. Если вы читали главу 9 книги Head First C#, то вы знаете, что можно вставить символы Unicode в Visual Studio и он знает, как обращаться с ними, хотя не знает, что иврит или арабские символы отображаются справа налево. Но если вы будете вставлять их в Блокнот, то действуйте аккуратно. Блокнот преобразовывает линии символов в знаки +, - и |. Будьте осторожны с этим при вставке кода программы WordFinder. В самом редакторе все выглядит как надо, но после сохранения файла вы «потеряете» линии из нужных символов.

Вы будете поражены, насколько сложную графику можно получить. Когда я делал анимацию в текстовом режиме, я использовал затемнение символьных блоков, которые в сочетании с цветом позволили мне сделать несколько сложных переходов. Сделайте себе одолжение и посмотрите скриншоты из игры The Amazing Adventures of ANSI Dude. Вы можете скачать игру здесь и запустить из DOSBox.
Прокрутка содержимого окна

Будет немного лучше, если вы измените размер окна чуть больше чем его содержимое. Это можно сделать, вызвав SetWindowSize() и установив свойства BufferWidth и BufferHeight. Добавьте следующий код в начало метода Main() файла CodePage437.cs:

1 // Избавиться от полосы прокрутки, делая буфер такого же размера, как и окно
2 Console.Clear();
3 Console.SetWindowSize(65, 33);
4 Console.BufferWidth = 65;
5 Console.BufferHeight = 33;

Теперь ваша программа должна будет выглядеть лучше. Обратили внимание, что появляется надпись «Press any key to continue…» (Нажмите клавишу для продолжения)? Это все потому, что я запускал ее из Visual Studio 2010. Обычно, когда вы запускаете консольное приложение из Visual Studio, то оно закрывается сразу же после окончания работы. Но если вы запускаете без отладчика (дебаггера), по нажатию Ctrl-F5, то будет отображаться эта строка. При этом отключается отладчик.

Вам нужно быть немного осторожными со свойствами буфера, потому что, если вы измените размер окна больше, чем буфер, то ваш код выдаст исключение. Причина в том, что окно должно быть всегда меньше чем буфер и, таким образом, окно может прокручиваться. Множество игр используют прокрутку для отображения лабиринта или боя. Для этого вы можете использовать свойства WindowLeft и WindowTop. Добавьте следующий код в конец файла CodePage437.cs и увидите, как работает скроллинг:

1 // Делаем окно меньше, чем буфер и скроллим
2 Console.SetWindowSize(20, 5);
3 for (int left = 5; left < 25; left++)
4 {
5      Console.WindowLeft = left;
6      System.Threading.Thread.Sleep(100);
7 }
8 for (int top = 5; top < 20; top++)
9 {
10      Console.WindowTop = top;
11      System.Threading.Thread.Sleep(100);
12 }
13 Сonsole.SetWindowSize(65, 33);

К сведению о вышесказанном. Существует возможность изменять кодировку текста используя свойство Console.OutputEncoding: