Подтвердить что ты не робот

С# Что-то быстрее, чем Console.Write()?

Я делаю игру, и перерисовка игрового поля не так хороша с Console.Write(), есть ли способ, чтобы я мог переписать все поле быстрее, не заставляя его выглядеть "лагги"? Практически все в игровом поле движется, но есть объекты только у элементов, отличных от 0.. (Здесь вы можете проверить полный код http://pastebin.com/TkPd37xD и посмотреть, что я я говорю о том, если моего описания недостаточно)

for (int Y = 0; Y < playfield.GetLength(0); Y++)
{
    for (int X = 0; X < playfield.GetLength(1); X++)
    {
        //destroying the row when it reaches the top
        if (playfield[0, X] != 0)
        {
            for (int i = 0; i < playfield.GetLength(1); i++)
            {
                playfield[0, X] = 0;
                Console.SetCursorPosition(X, 0);
                Console.Write(" ");
            }
        }
        if (playfield[Y, X] == 3)
        {
            playfield[Y - 1, X] = 3;
            playfield[Y, X] = 0;
        }
        else if (playfield[Y, X] == 1)
        {
            Console.SetCursorPosition(X, Y - 1);
            Console.Write("=");
            playfield[Y - 1, X] = 1;
            Console.SetCursorPosition(X, Y);
            Console.Write(" ");
            playfield[Y, X] = 0;
        }
        else if (playfield[Y, X] == 0)
        {
            Console.SetCursorPosition(X, Y);
            Console.Write(" ");
        }
    }
}
4b9b3361

Ответ 1

В основном два подхода: меньше визуализировать и рендерить.

Render less обычно более сложный, но также имеет тенденцию быть менее интенсивным. Классическим примером были бы игры Carmack Keen - у ПК не хватало смелости, чтобы переустановить весь экран сразу, поэтому Carmack удостоверился, что только части экрана, которые на самом деле меняются, перерисовываются. В вашем случае это может быть так же просто, как проверка нового экрана на старый экран (без использования методов Console, конечно) - в зависимости от типа игры, которую вы пишете, это может сэкономить вам огромное количество работа.

Быстрое рендеринг обычно проще. Обычный подход в прежние времена заключался в том, чтобы получить прямой доступ к выходному буферу - вместо того, чтобы иметь игровое поле в отдельной памяти, вы имели его прямо на графической карте, - которая была вполне способна перерисовывать весь экран так быстро, как нужно, Конечно, так как иначе вы никогда не увидите многого на экране CRT. Этот параметр по-прежнему доступен как обратная совместимость, поэтому вы все равно можете использовать его, если вы кодируете приложение, скажем, Turbo Pascal, но это не все, что легко доступно на С#. Существует опция для отображения всего экрана в StringBuilder сначала, а затем Console.Write, что все сразу. Это будет совсем немного быстрее, но это не совсем звездно. char[] позволит вам получить дополнительную производительность - вы можете представлять свое игровое поле непосредственно как char[][], а затем вам не нужно воссоздавать StringBuilder каждый раз, когда вы что-то меняете - вам просто нужно Console.Write один раз для каждой линии игрового поля.

И, конечно же, вы можете просто записать изменения, как только они появятся; в зависимости от игры, которую вы пишете, это может варьироваться от "тривиального с большими результатами" до "довольно жесткого и не выглядящего хорошо". И так как буферная область консоли может быть больше, чем размер окна, вы можете даже вытащить ее в скрытую часть буфера, а затем использовать Console.MoveBufferArea для рисования всего изменения сразу - это обычно называют "backbuffering". Я не уверен, что это будет выглядеть хорошо, хотя теперь окно консоли позволяет прокручивать в буфере, который может быть некриминальным для вашего прецедента.

По-прежнему есть способы получить гораздо более быстрый доступ к буферам консоли, но не при полном пребывании в .NET - вам нужно будет использовать P/Invokes. Отличный ответ на эту тему здесь - Как написать быстрый цветной вывод на консоль?. В современных системах это в значительной степени эквивалентно использованию заднего буфера и "рисованию" всего сразу - это невероятно быстро. И снова вы можете напрямую использовать задний буфер для своих игровых данных - он работал 20-30 лет назад, и он по-прежнему работает сегодня; это хорошая практика в игре с ограниченными ресурсами. Можете ли вы написать игру, которая на самом деле использует консольный текстовый буфер для всего, или, по крайней мере, почти все? Это довольно весело, играя с такими вещами; вы можете написать целую массу таких игр, включая такие игры, как Tetris или Lode Runner. Конечно, это будет работать только в Windows, поэтому, если вы хотите поддерживать другие системы, это намного сложнее.

И, наконец, вы можете просто написать свою собственную консоль (или, лучше, использовать кого-то уже написанного и протестированного). Это хорошая практика, если с течением времени вы захотите перейти к более сложным задачам, и это позволит вам играть с более мощными технологиями с течением времени. Типичным примером могут быть такие игры, как Dwarf Fortress - все еще текстовые, все еще консольные, но на самом деле рисуются графически, используя такие технологии, как SDL. Это не только значительно ускоряет работу на современных системах (поскольку у вас нет простого способа получить доступ к текстовым буферам напрямую), он также позволяет легко перейти на графическую черепичную игру. Это еще один шаг на лестнице, чтобы охладить вещи:))

Ответ 2

Альтернативой является использование вызова API, указанного в ссылке https://msdn.microsoft.com/en-gb/library/windows/desktop/aa363362%28v=vs.85%29.aspx

[DllImport("kernel32.dll")]
static extern void OutputDebugString(string lpOutputString);

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

Ответ 3

Если вы скрываете окно вывода cmd, окна не перерисовывают его, и приложение работает быстрее, чем если оно открыто на экране.

Если это просто проблема отладки, вы можете просто свернуть окно и увидеть небольшое увеличение производительности.