где взять код для игры

Почему никак не узнать исходный код игры?

Объясните пожалуйста, почему я никогда не узнаю исходный код какой-нибудь игры пока разработчики его сами не выложат в открытый доступ или хакеры его не сольют?

В обычных приложениях его можно узнать через DotPeek, но в большинстве игр нет.

Почему нельзя узнать исходный код, как например достать текстуры из игры?
Почему после компиляции всё?
Если это всё как-то шифруют, то как работает эта шифровка?

Я понимаю вопросы глупые, но объясните мне пожалуйста как дурачку. Я просто не могу этого понять. =(

(Объясните пожалуйста на простых словах, без википедии, я не понимаю что там написано)

где взять код для игры. 5e34b2cccf6be898763470. где взять код для игры фото. где взять код для игры-5e34b2cccf6be898763470. картинка где взять код для игры. картинка 5e34b2cccf6be898763470. Объясните пожалуйста, почему я никогда не узнаю исходный код какой-нибудь игры пока разработчики его сами не выложат в открытый доступ или хакеры его не сольют?

где взять код для игры. 9a296065d69846c09d50d501eb101c6b. где взять код для игры фото. где взять код для игры-9a296065d69846c09d50d501eb101c6b. картинка где взять код для игры. картинка 9a296065d69846c09d50d501eb101c6b. Объясните пожалуйста, почему я никогда не узнаю исходный код какой-нибудь игры пока разработчики его сами не выложат в открытый доступ или хакеры его не сольют?

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

где взять код для игры. 5e09db84edf13557072665. где взять код для игры фото. где взять код для игры-5e09db84edf13557072665. картинка где взять код для игры. картинка 5e09db84edf13557072665. Объясните пожалуйста, почему я никогда не узнаю исходный код какой-нибудь игры пока разработчики его сами не выложат в открытый доступ или хакеры его не сольют?

где взять код для игры. f45024bcc7d7567f4c4296de5d36c0b3. где взять код для игры фото. где взять код для игры-f45024bcc7d7567f4c4296de5d36c0b3. картинка где взять код для игры. картинка f45024bcc7d7567f4c4296de5d36c0b3. Объясните пожалуйста, почему я никогда не узнаю исходный код какой-нибудь игры пока разработчики его сами не выложат в открытый доступ или хакеры его не сольют?

где взять код для игры. 5fc6bcae02e83394447533. где взять код для игры фото. где взять код для игры-5fc6bcae02e83394447533. картинка где взять код для игры. картинка 5fc6bcae02e83394447533. Объясните пожалуйста, почему я никогда не узнаю исходный код какой-нибудь игры пока разработчики его сами не выложат в открытый доступ или хакеры его не сольют?

Потому куда важнее дать пояснение чем просто посмотреть чужой код

Источник

Заглянем за кулисы разработки: подборка исходных кодов классических игр

Обожаю заглядывать за кулисы. Мне интересно, как делаются вещи. Мне кажется, что большинству людей это тоже интересно.

Исторически так сложилось, что видеоигры не делятся исходниками. Конечно, они ведь предназначены для игроков. Но для программистов там всегда есть, на что посмотреть. И некоторые игры всё-таки выпускали свои исходники. А я давно намеревался сделать такую подборку.

К сожалению, почти все игры – для PC. Найти исходники для консолей или аркад почти нереально, и большинство программистов не в курсе различий подходов к программам на платформах, отличных от PC.

Многие игры после выпуска исходников были улучшены и дополнены сообществом – я намеренно даю ссылки только на оригинальные исходники. Так что, если вас вдруг интересуют апгрейды – они могут существовать.

Многие игры были рассмотрены на сайте Fabien Sanglard. Если вам интересны подробности их работы, то пожалуйте к нему.

Можно заметить, что многие игры принадлежат id Software/Apogee. Совпадение? Не думаю. id славится открытостью и привычкой выпускать исходники. Старые коммерческие игры уже не имеют ценности и были бы потеряны – не лучше ли, чтобы кто-то учился чему-то полезному на их основе?

Итак, приступим (в хронологическом порядке):

Colossal Cave Adventure (1976)

где взять код для игры. image loader. где взять код для игры фото. где взять код для игры-image loader. картинка где взять код для игры. картинка image loader. Объясните пожалуйста, почему я никогда не узнаю исходный код какой-нибудь игры пока разработчики его сами не выложат в открытый доступ или хакеры его не сольют?

Разработчик: William Crowther and Don Woods
Издатель: Разные.
Платформа: PDP-10 и друзья.

“You are in a maze of twisty little passages, all alike.” («Вы находитесь в лабиринте из неотличимых друг от друга небольших извилистых проходов»).

Возможно, это не на 100% коммерческая игра. Но её продавали, кроме того, она имеет историческую важность. И, кстати, именно по мотивам названия этой игры все приключенческие игры называются adventure.

Оригинал был написан на Fortran, в котором современным программистам будет сложновато разобраться. Но последние версии были на C.

Catacomb (1989)

где взять код для игры. image loader. где взять код для игры фото. где взять код для игры-image loader. картинка где взять код для игры. картинка image loader. Объясните пожалуйста, почему я никогда не узнаю исходный код какой-нибудь игры пока разработчики его сами не выложат в открытый доступ или хакеры его не сольют?

Разработчик: John Carmack
Издатель: Softdisk
Платформа: Apple II / DOS

Не путайте с Catacomb 3D. Это ранняя двумерная версия игры. Разработана Кармаком до создания id и полностью написана на Turbo Pascal.

Prince Of Persia (1989)

где взять код для игры. image loader. где взять код для игры фото. где взять код для игры-image loader. картинка где взять код для игры. картинка image loader. Объясните пожалуйста, почему я никогда не узнаю исходный код какой-нибудь игры пока разработчики его сами не выложат в открытый доступ или хакеры его не сольют?

Разработчик: Jordan Mechner
Издатель: Brøderbund
Платформа: Apple II / DOS / many more
Обзор кода: fabiensanglard.net

Prince Of Persia произвёл фурор благодаря плавной анимации, голливудскому стилю подачи истории и интересному геймплею.

Написана полностью на ассемблере, что затрудняет задачу обзора кода. Рекомендую посмотреть интервью с Джорданом Мехнером, где он делится деталями о создании игры.

SimCity (1989)

где взять код для игры. image loader. где взять код для игры фото. где взять код для игры-image loader. картинка где взять код для игры. картинка image loader. Объясните пожалуйста, почему я никогда не узнаю исходный код какой-нибудь игры пока разработчики его сами не выложат в открытый доступ или хакеры его не сольют?

Разработчик: Maxis
Издатель: Maxis / Brøderbund
Платформа: All

Игра начала новый жанр. В основе алгоритма – симуляция города посредством клеточных алгоритмов. Хороший пример кода, который стоит изучить для понимания принципов работы. Исходники для unix-порта 1990 года были выпущены в 2008 году.

Hovertank 3D / Catacomb 3D (1991)

где взять код для игры. image loader. где взять код для игры фото. где взять код для игры-image loader. картинка где взять код для игры. картинка image loader. Объясните пожалуйста, почему я никогда не узнаю исходный код какой-нибудь игры пока разработчики его сами не выложат в открытый доступ или хакеры его не сольют?

Разработчик: id Software
Издатель: Softdisk
Платформа: DOS

Первая веха в истории трёхмерных шутеров id Software. Эти игры используют технику raycasting, которая была улучшена в следующем хите, Wolfenstein, где были добавлены текстуры.

Star Control II (1992)

где взять код для игры. image loader. где взять код для игры фото. где взять код для игры-image loader. картинка где взять код для игры. картинка image loader. Объясните пожалуйста, почему я никогда не узнаю исходный код какой-нибудь игры пока разработчики его сами не выложат в открытый доступ или хакеры его не сольют?

Разработчик: Toys for Bob
Издатель: Accolade
Платформа: DOS / 3D0

Уникальная игра, не вписывающаяся ни в один из строгих жанров. Внешний вид чётко напоминает нам о 90-х годах и системе VGA, где цвета были подобраны не для красоты, а из стандартной палитры DPaint.

Рекомендую почитать обзор кода от The Escapist.

Исходник получен с порта на 3D0, оригинальный же был утерян. Это часто случается со старыми играми, когда разработчики уходят из компании.

Wolfenstein 3D / Blake Stone (1992/3)

где взять код для игры. image loader. где взять код для игры фото. где взять код для игры-image loader. картинка где взять код для игры. картинка image loader. Объясните пожалуйста, почему я никогда не узнаю исходный код какой-нибудь игры пока разработчики его сами не выложат в открытый доступ или хакеры его не сольют?

На основе предыдущего движка Catacomb был сделан серьёзный апгрейд на VGA-графику. И играть стало интереснее. Как в большинстве случаев с компанией id, исходники сравнительно легко читать, хотя ключевые части написаны на 16-битном ассемблере (в Doom уже такого не встретишь).

Интересно отметить, что для рисования вертикальных линий они динамически генерируют разные функции для каждой из возможных высот стен.

У Fabien можно найти инструкцию по компиляции исходников на современных инструментах.

Blake Stone, ответвление от Apogee на том же движке, вышло в 1993 году, за неделю до Doom. Можно представить, почему оно кануло в лету.

Doom (1993)

где взять код для игры. image loader. где взять код для игры фото. где взять код для игры-image loader. картинка где взять код для игры. картинка image loader. Объясните пожалуйста, почему я никогда не узнаю исходный код какой-нибудь игры пока разработчики его сами не выложат в открытый доступ или хакеры его не сольют?

В каком-то смысле это самый важный для изучения движок. В своё время это была революция – мир от первого лица, не плоский, как Wolf3D. Освещение, текстуры и изобретение DeathMatch.

Одной из самых знаковых вещей стало изобретение идеи «движка». До этого игры были сильно связаны с данными. Doom пропагандировал отвязку данных игры от движка. Это породило целые сообщества, модифицировавшие игры (Aliens TC, Fistful Of Doom).

Descent (1994)

где взять код для игры. 932903db66f65ea4273638dd8fa9d9a6. где взять код для игры фото. где взять код для игры-932903db66f65ea4273638dd8fa9d9a6. картинка где взять код для игры. картинка 932903db66f65ea4273638dd8fa9d9a6. Объясните пожалуйста, почему я никогда не узнаю исходный код какой-нибудь игры пока разработчики его сами не выложат в открытый доступ или хакеры его не сольют?

Многие компании кинулись догонять Doom, запустив волну «Клонов Doom». Parallax удалось сделать нечто совсем другое.

В игре можно было летать на корабле по трёхмерному лабиринту из проходов, в отличие от 2.5D коридоров Doom (у id полная трёхмерность появилась лишь в Quake год спустя).

Gravity Force 2 (1994)

где взять код для игры. image loader. где взять код для игры фото. где взять код для игры-image loader. картинка где взять код для игры. картинка image loader. Объясните пожалуйста, почему я никогда не узнаю исходный код какой-нибудь игры пока разработчики его сами не выложат в открытый доступ или хакеры его не сольют?

Разработчик: Jens Andersson and Jan Kronqvist
Издатель: Shareware
Платформа: Amiga

Многие современники вспомнят эту игру. Amiga Power однажды назвала её второй лучшей игрой всех времён.

Это не совсем коммерческая игра, она была выпущена по принципу платного shareware, а затем её раздавали бесплатно на диске Amiga Power. Включил её в список потому, что в ту пору вообще редкие игры выдавали свои исходники. Если вам интересно, как делались 16-битные игры, обратите внимание.

Heretic / Hexen (1994/5)

где взять код для игры. c86ac0c8d02efe8f315bae821af2510c. где взять код для игры фото. где взять код для игры-c86ac0c8d02efe8f315bae821af2510c. картинка где взять код для игры. картинка c86ac0c8d02efe8f315bae821af2510c. Объясните пожалуйста, почему я никогда не узнаю исходный код какой-нибудь игры пока разработчики его сами не выложат в открытый доступ или хакеры его не сольют?

Это был уникальный клон Doom по двум причинам: 1) лицензированный движок Doom и 2) хороший геймплей

Заметные улучшения: возможность смотреть вверх и вниз, скриптовой движок для внутриигровых событий (новая идея на то время).

Rise Of The Triad: Dark War (1995)

где взять код для игры. image loader. где взять код для игры фото. где взять код для игры-image loader. картинка где взять код для игры. картинка image loader. Объясните пожалуйста, почему я никогда не узнаю исходный код какой-нибудь игры пока разработчики его сами не выложат в открытый доступ или хакеры его не сольют?

ROTT это была странная игра. Она была порождена движком Wolfenstein 3D, при этом создатели умудрились эмулировать ощущения разных высот. Но всё равно игра не смогла конкурировать с Doom от 1993 года.

Marathon 2: Durandal (1995)

где взять код для игры. image loader. где взять код для игры фото. где взять код для игры-image loader. картинка где взять код для игры. картинка image loader. Объясните пожалуйста, почему я никогда не узнаю исходный код какой-нибудь игры пока разработчики его сами не выложат в открытый доступ или хакеры его не сольют?

Разработчик: Bungie Software
Издатель: Bungie Software
Платформа: Apple Macintosh / Windows 95

Серия отличилась тем, что в своё время попала в крайне маленький список игр, доступных на Apple Macintosh. И, в общем-то, это клон Doom. А через 3 месяца после её выхода id Software выпустила знаменитый “qtest”, позволявший взглянуть на движок Quake.

Поскольку Маки тогда использовали лишь писатели с художниками, несмотря на все усилия, серия провалилась. Небольшая компания разработчиков имела неплохой успех на разных других платформах.

Duke Nukem 3D / Shadow Warrior (1996)

где взять код для игры. 9d9df67d5eaa47d89501a3d35bc92ed3. где взять код для игры фото. где взять код для игры-9d9df67d5eaa47d89501a3d35bc92ed3. картинка где взять код для игры. картинка 9d9df67d5eaa47d89501a3d35bc92ed3. Объясните пожалуйста, почему я никогда не узнаю исходный код какой-нибудь игры пока разработчики его сами не выложат в открытый доступ или хакеры его не сольют?

Разработчик: 3D Realms
Издатель: GT Interactive Software
Платформа: DOS
Code review: fabiensanglard.net

Из множества клонов, игры 3D Realms отличились хорошими попытками привнести нечто новое в игру. Движок Кена Сильвермана Build Engine добавил много интересных фич вроде наклонных полов, комнат, расположенных друг над другом и зеркал.

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

За дополнительной информацией обращайтесь на страницу автора.

Quake 1/2/3 (1996-1999)

где взять код для игры. image loader. где взять код для игры фото. где взять код для игры-image loader. картинка где взять код для игры. картинка image loader. Объясните пожалуйста, почему я никогда не узнаю исходный код какой-нибудь игры пока разработчики его сами не выложат в открытый доступ или хакеры его не сольют?

Разработчик: id Software
Издатель: GT Interactive / Activision
Платформа: DOS / Windows / others
Code review: fabiensanglard.net (Quake 1)
Code review: fabiensanglard.net (Quake 3)

Тут писать особо нечего, вы и сами всё знаете. Знатная веха в создании полностью трёхмерных движков, без всяких хаков вроде 2.5D

Упомяну несколько интересных подробностей. Возможно, это первая коммерческая игра, скомпилированная компилятором с открытым исходным кодом (DJGPP for DOS, ранний порт gcc).

В игре был свой скриптовой язык “Quake C” (позже lcc у Quake 3). Он был встроен специально для того, чтобы игроки могли делать модификации. Это, вкупе с системой ресурсов PWAD, породило огромное сообщество моддеров.

В Quake 1 был инновационный механизм кэширования результатов шейдинга. Но после распространения 3D-ускорителей это потеряло смысл. Следующая игра от id, Rage, использовала эту же идею.

Кроме того, Quake был очень надёжным движком. Никаких глюков растра или обсчёта столкновений.

Abuse (1996)

где взять код для игры. image loader. где взять код для игры фото. где взять код для игры-image loader. картинка где взять код для игры. картинка image loader. Объясните пожалуйста, почему я никогда не узнаю исходный код какой-нибудь игры пока разработчики его сами не выложат в открытый доступ или хакеры его не сольют?

Разработчик: Crack dot Com
Издатель: Electronic Arts / Origin Systems
Платформа: DOS / Linux / Mac

В игре было использовано несколько инноваций. Крутая система управления одновременно с мыши и клавиатуры. Динамическое освещение (неслыханная вещь для платформеров).

Но больше всего, как программисту, мне понравилась система «визуального Lisp». Вся игра заскриптована на языке, напоминающем Lisp. Поведение врагов можно изменять во время выполнения игры, а не просто включать в код.

Ещё одним интересным моментом стал способ, по которому события можно подключать во встроенном редакторе карт – визуально перетаскивать линии от выключателя к двери, или от ловушки к месту, где появляются враги. Присутствует возможность задавать логику И/ИЛИ в виде скрытых объектов на уровне. Такого я в других редакторах не встречал.

Коммерческого успеха игра не снискала и через два года исходники были опубликованы. Следующая игра от Crack Dot Com, Golgotha, была выпущена по принципу open-source, включая всю графику.

Aliens versus Predator (1999)

где взять код для игры. fe9602a46f2f15e68d301c9a2c1435fe. где взять код для игры фото. где взять код для игры-fe9602a46f2f15e68d301c9a2c1435fe. картинка где взять код для игры. картинка fe9602a46f2f15e68d301c9a2c1435fe. Объясните пожалуйста, почему я никогда не узнаю исходный код какой-нибудь игры пока разработчики его сами не выложат в открытый доступ или хакеры его не сольют?

Какое облегчение видеть здесь шутер не за авторством id. И хотя технических инноваций в игре особо не было, сингл-кампания у неё вышла просто потрясающей. И игра остаётся хорошим примером движка не от id.

Freespace 2 (1999)

где взять код для игры. 895f27d7a6477355a83f37c69c411210. где взять код для игры фото. где взять код для игры-895f27d7a6477355a83f37c69c411210. картинка где взять код для игры. картинка 895f27d7a6477355a83f37c69c411210. Объясните пожалуйста, почему я никогда не узнаю исходный код какой-нибудь игры пока разработчики его сами не выложат в открытый доступ или хакеры его не сольют?

Как бы наследник франшизы Descent, но не совсем. Кампания и мультиплеер проходят полностью в космическом пространстве.

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

The Operative: No One Lives Forever (2000)

где взять код для игры. 8e7d4c4d28d59723e4b5ebe95e72a3e2. где взять код для игры фото. где взять код для игры-8e7d4c4d28d59723e4b5ebe95e72a3e2. картинка где взять код для игры. картинка 8e7d4c4d28d59723e4b5ebe95e72a3e2. Объясните пожалуйста, почему я никогда не узнаю исходный код какой-нибудь игры пока разработчики его сами не выложат в открытый доступ или хакеры его не сольют?

У движка LithTech история долгая, хотя он и находится в тени более известных Quake и Unreal engine. Я особенно не рылся в исходника NOLF, но я подозреваю, что там есть лишь исходники самой игры, но не графического движка. И однозначно там не будет частей, связанных с работой на PlayStation 2.

А жаль – разработка для PS2 в наши дни должна выглядеть для программистов инопланетным делом, поскольку она гораздо сильнее подходила в методу ориентации на данные, чем это делают современные API.

MechCommander 2 (2001)

где взять код для игры. c088d3ebda463dbcf2c3f9df25758edd. где взять код для игры фото. где взять код для игры-c088d3ebda463dbcf2c3f9df25758edd. картинка где взять код для игры. картинка c088d3ebda463dbcf2c3f9df25758edd. Объясните пожалуйста, почему я никогда не узнаю исходный код какой-нибудь игры пока разработчики его сами не выложат в открытый доступ или хакеры его не сольют?

Разработчик: FASA Interactive
Издатель: Microsoft
Платформа: Windows

Исторически Microsoft и открытые исходные коды вместе не уживались. Но на склоне лет ситуация начинает смягчаться. Всё-таки приятно видеть, что большие компании приходят к более открытым взглядам на вещи – все эти наработки имеют нулевую коммерческую ценность, они ценны лишь исторически.

В прошлом году даже были выпущены исходники ранних версий MS-DOS и Word, что было неслыханным делом лет 30 назад.

Doom 3 (2004)

где взять код для игры. 0e5df8e035493950310fb8b768b322f2. где взять код для игры фото. где взять код для игры-0e5df8e035493950310fb8b768b322f2. картинка где взять код для игры. картинка 0e5df8e035493950310fb8b768b322f2. Объясните пожалуйста, почему я никогда не узнаю исходный код какой-нибудь игры пока разработчики его сами не выложат в открытый доступ или хакеры его не сольют?

Разработчик: id Software
Издатель: Activision
Платформа: Windows / Mac / Linux / Xbox / PS3
Code review: fabiensanglard.net

Если вы хотите изучить движки современных игр высшего класса, то Doom 3 – это один из наилучших примеров. На время выхода он был инновационным во многих областях. Метод использования моделей высокого разрешения на элементах низкого разрешения в игре сейчас является стандартом для коммерческих игр. В исходнике есть много всего интересного – одна лишь система обработки физики достойна изучения, в частности, отслеживание столкновений.

Это первая игра от id, написанная на С++. Прошлые игры из-за использования С несли в себе простоту. Doom 3 тоже довольно простой, но заметно уже изменение его вектора движения.

Также игра (печально) известна использованием трафаретных теней при расчёте освещения. Можно спорить, был это интересный эксперимент или поле для дальнейшей работы, но сегодняшние игры предпочитают использовать карты теней. Возможно, эта техника когда-нибудь ещё пригодится.

Gish (2004)

где взять код для игры. 243906f7ca5719321c93ceb0fcaf8d96. где взять код для игры фото. где взять код для игры-243906f7ca5719321c93ceb0fcaf8d96. картинка где взять код для игры. картинка 243906f7ca5719321c93ceb0fcaf8d96. Объясните пожалуйста, почему я никогда не узнаю исходный код какой-нибудь игры пока разработчики его сами не выложат в открытый доступ или хакеры его не сольют?

Разработчик: Cryptic Sea
Издатель: Chronic Logic / Stardock
Платформа: Windows / Linux

Gish был примечателен физикой «мягкого тела» и интересным подходом ко времени. Интересно разбираться в его исходниках и выяснять, как что работает. Никаких сторонних физических движков тут нет.

Интересно, что игра полностью написана на С – сейчас это редко встречается. Это не самый аккуратный из всех виденных мною исходников, но это хороший пример того, как игра может не превращаться в гигантскую расползшуюся базу кода с сотнями внешних зависимостей.

Canabalt (2009)

где взять код для игры. 97aa5158beeff6caebd1d3ba38ed28ff. где взять код для игры фото. где взять код для игры-97aa5158beeff6caebd1d3ba38ed28ff. картинка где взять код для игры. картинка 97aa5158beeff6caebd1d3ba38ed28ff. Объясните пожалуйста, почему я никогда не узнаю исходный код какой-нибудь игры пока разработчики его сами не выложат в открытый доступ или хакеры его не сольют?

Разработчик: Adam Saltsman
Издатель: Semi-Secret / Beatshapers / Kittehface
Платформа: Flash / iOS / PSP / Android / Ouya

Не самая сложная игра, ну и что? Если вы хотите научиться делать игры, начинайте с простого – вот с этого.

Прототипирование заняло 5 дней, портирование на iOS – 10. Пример превращения простой идеи в достойное выражение. Это как бы возвращение 8-битной эпохи, когда еженедельно могли появляться новые жанры. Жаль, что с тех пор люди предпочитают клонировать идеи, а не творить самостоятельно.

Canabalt показывает, насколько вещи можно сделать просто, если захотеть.

Что я упустил

Нужно упомянуть ещё несколько игр. Они не выпускали исходников, но подверглись фанатскому обратному инжинирингу. Это, конечно, не то же самое, что настоящие исходники, но тоже может быть интересным:

Не попали в рейтинг

Сорцы следующих игр утекли в сеть нелегально, поэтому они не попали в зал славы:

Half Life 2
Falcon 4.0
ReVolt
Turrican III
Mr. Nutz: Hoppin’ Mad
Trespasser (ладно уж, вот вам обзор кода)

Источник

Как написать игру на C++

О чем статья?

Оглавление

Что нужно знать, чтобы понять статью?

Обработка действий игрока в реальном времени

Запуск периодических событий по таймеру

Генератор случайных чисел

Изменение размера экрана консоли

Ускорение вывода текста

Вывод готовых фрагментов текста

Настройка буферизации stdio.h

Мотивация

Зачем так делать?

Почему C++?

Главная причина в том, что я сейчас веду индивидуальные занятия по C++ у одного талантливого студента. Его успехи вдохновили меня, а его вопросы показали о чем вообще нужно написать. C++ до сих пор рекомендуют как «язык для обучения». Это вселяет надежду, что статья будет полезна многим. Может быть когда-нибудь я напишу такую же статью и для других языков или для Linux, но не рассчитывайте на это. Если вы напишете сами подобный сборник советов для другого языка, то сообщите мне личным сообщением. Я добавлю ссылку на ваш труд.

Что нужно знать, чтобы понять статью?

Обработка действий игрока в реальном времени

Windows API

Поиск по ключевым словам «handle C++ event» выдало целую кучу бесполезной информации по рисованию окон в каком-то из фреймворков windows. Я все еще намерен писать простую игру в консоли, а не оконное приложение, поэтому игнорирую результаты.

Следующая попытка была «cpp event loop with console input» и мне попалась статья https://docs.microsoft.com/en-us/windows/console/reading-input-buffer-events из которой я и взял решение. Считаю это удачной находкой, потому что в процессе написания этой статьи пытался вспомнить свои запросы и даже слегка видоизмененный «event loop c++ with console application» уже не давал нужной информации. Пришлось смотреть историю поиска. Для будущих поколений я добавил сюда явный текст своих запросов, в надежде что будущие поиски будут более результативными.

Подстава в том, что даже эта статья на самом деле показывает пример блокирующего чтения «The function [ReadConsoleInput] does not return until at least one record is available to be read.» Поэтому я посмотрел на соседние статьи и нашел обзор низкоуровневых функций чтения https://docs.microsoft.com/en-us/windows/console/low-level-console-input-functions

В ней описана функция PeekConsoleInput, которая «If no records are available, the function returns immediately.», но которая при этом «Reads without removing the pending input records in an input buffer.». То есть если ее вызвать несколько раз подряд, то она получит информацию об одних и тех же событиях. К счастью там же еще описана функция FlushConsoleInputBuffer, которая удаляет все непрочитанные накопленные события. Сочетание этих двух функций позволит добиться нужного эффекта.

Я видоизменил код из найденной статьи https://docs.microsoft.com/en-us/windows/console/reading-input-buffer-events а именно:

Удалил обработку событий мыши. Если понадобится, спишите ее сами из оригинала.

Удалил колдовство над режимом консоли (функции GetConsoleMode/SetConsoleMode). Для обработки клавиатуры подходит и стандартный режим. Это позволило упростить обработку ошибок в функции ErrorExit.

Добавил сквозной счетчик итераций внешнего цикла. Чтобы было видно работу программы при отсутствии событий.

Получилось вот так:

где взять код для игры. 515e1a586c862259b8ade50a688ccecd. где взять код для игры фото. где взять код для игры-515e1a586c862259b8ade50a688ccecd. картинка где взять код для игры. картинка 515e1a586c862259b8ade50a688ccecd. Объясните пожалуйста, почему я никогда не узнаю исходный код какой-нибудь игры пока разработчики его сами не выложат в открытый доступ или хакеры его не сольют?Обработка событий клавиатуры в консоли Windows API

где взять код для игры. ee7849aeeea3e053dc508e3503c1c734. где взять код для игры фото. где взять код для игры-ee7849aeeea3e053dc508e3503c1c734. картинка где взять код для игры. картинка ee7849aeeea3e053dc508e3503c1c734. Объясните пожалуйста, почему я никогда не узнаю исходный код какой-нибудь игры пока разработчики его сами не выложат в открытый доступ или хакеры его не сольют?Результат запуска обработки событий клавиатуры в консоли Windows API

Допустим мы увидели как обрабатывать события клавиатуры не останавливая работу программы. Что можно с этим сделать?

Чтобы собрать больше информации, я поставил точку останова в функции обработки события и понажимал разные кнопки.

Анализ результатов в отладчике

Например вот так выглядит событие при нажатии «ж».

где взять код для игры. 24b79e96be30e54aa370d50e0dfb6015. где взять код для игры фото. где взять код для игры-24b79e96be30e54aa370d50e0dfb6015. картинка где взять код для игры. картинка 24b79e96be30e54aa370d50e0dfb6015. Объясните пожалуйста, почему я никогда не узнаю исходный код какой-нибудь игры пока разработчики его сами не выложат в открытый доступ или хакеры его не сольют?

где взять код для игры. 24cb190bef8ef26c13936b8e776dac81. где взять код для игры фото. где взять код для игры-24cb190bef8ef26c13936b8e776dac81. картинка где взять код для игры. картинка 24cb190bef8ef26c13936b8e776dac81. Объясните пожалуйста, почему я никогда не узнаю исходный код какой-нибудь игры пока разработчики его сами не выложат в открытый доступ или хакеры его не сольют?

где взять код для игры. 5a60b18ce549892f8ee4acd5c3bab8d3. где взять код для игры фото. где взять код для игры-5a60b18ce549892f8ee4acd5c3bab8d3. картинка где взять код для игры. картинка 5a60b18ce549892f8ee4acd5c3bab8d3. Объясните пожалуйста, почему я никогда не узнаю исходный код какой-нибудь игры пока разработчики его сами не выложат в открытый доступ или хакеры его не сольют?

где взять код для игры. 015079d8a7812b86a33a8f48157db028. где взять код для игры фото. где взять код для игры-015079d8a7812b86a33a8f48157db028. картинка где взять код для игры. картинка 015079d8a7812b86a33a8f48157db028. Объясните пожалуйста, почему я никогда не узнаю исходный код какой-нибудь игры пока разработчики его сами не выложат в открытый доступ или хакеры его не сольют?

где взять код для игры. 65c16a8e7a6dc5d2d5638cf8eb3c2037. где взять код для игры фото. где взять код для игры-65c16a8e7a6dc5d2d5638cf8eb3c2037. картинка где взять код для игры. картинка 65c16a8e7a6dc5d2d5638cf8eb3c2037. Объясните пожалуйста, почему я никогда не узнаю исходный код какой-нибудь игры пока разработчики его сами не выложат в открытый доступ или хакеры его не сольют?

где взять код для игры. ad2cb29a86b7157d9ed4123100c5e953. где взять код для игры фото. где взять код для игры-ad2cb29a86b7157d9ed4123100c5e953. картинка где взять код для игры. картинка ad2cb29a86b7157d9ed4123100c5e953. Объясните пожалуйста, почему я никогда не узнаю исходный код какой-нибудь игры пока разработчики его сами не выложат в открытый доступ или хакеры его не сольют?

Обратите внимание, что во всех вариантах нажатия на кнопку «ж», «Ж», «;» в поле wVirtualKeyCode находится одно и то же число. Если использовать это поле, то управление не будет зависеть от раскладки и даже от зажатого шифта и капслока.

Еще важный момент, что wVirtualKeyCode для точки с запятой «;» на разных клавишах разный, но uChar.UnicodeChar у них одинаковый.

Итого с помощью Windows API мы можем:

Различать нажатые клавиши по коду клавиши независимо от раскладки

Различать нажатые клавиши по коду из Юникода независимо от их расположения на клавиатуре.

Обрабатывать нажатия на shift, ctrl, alt.

Понимать, нажат ли сейчас shift, ctrl, alt.

Отличать нажатие клавиши и ее отпускание (буду благодарен, если подберете слово получше).

Прикрутить обработку событий мыши

где взять код для игры. 167718dede2bf500410bb538edc405b7. где взять код для игры фото. где взять код для игры-167718dede2bf500410bb538edc405b7. картинка где взять код для игры. картинка 167718dede2bf500410bb538edc405b7. Объясните пожалуйста, почему я никогда не узнаю исходный код какой-нибудь игры пока разработчики его сами не выложат в открытый доступ или хакеры его не сольют?

В обработчик нажатия клавиш добавил ветвление. В нем проверяется код клавиши и увеличивается соответствующая переменная.

где взять код для игры. af40bfb95fa820bca23076eeb13fb588. где взять код для игры фото. где взять код для игры-af40bfb95fa820bca23076eeb13fb588. картинка где взять код для игры. картинка af40bfb95fa820bca23076eeb13fb588. Объясните пожалуйста, почему я никогда не узнаю исходный код какой-нибудь игры пока разработчики его сами не выложат в открытый доступ или хакеры его не сольют?

Для проверки запустил и нажал вниз 1 раз, вправо 2 раза, вверх 3 раза, влево 4 раза. Получился вывод как на картинке. Чтобы сделать скриншот, пришлось подключить отладчик.

где взять код для игры. a631ed6c1e1c53814a936d3a0e039f2a. где взять код для игры фото. где взять код для игры-a631ed6c1e1c53814a936d3a0e039f2a. картинка где взять код для игры. картинка a631ed6c1e1c53814a936d3a0e039f2a. Объясните пожалуйста, почему я никогда не узнаю исходный код какой-нибудь игры пока разработчики его сами не выложат в открытый доступ или хакеры его не сольют?

conio.h + getch

Мой студент параллельно мне нашел способ обрабатывать нажатия на кнопки с помощью комбинации функций kbhit и getch из conio.h. С помощью getch можно получить код нажатого символа, но эта функция ждет следующего нажатия. Чтобы программа при этом продолжала работать, нужно сначала вызвать kbhit. Эта функция вернет true, если нажата хотя бы одна клавиша, но при следующего нажатия ждать не будет. Если ничего не нажато, то kbhit возвращает false и программа работает дальше.

К сожалению, я сходу не разобрался, в какой кодировке этот код для кириллических символов. Я реализовал прототип с помощью conio и поэкспериментировал с нажатием клавиш. Эта библиотека игнорирует нажатие shift, ctrl, alt, caps lock. Точка с запятой «;» на клавише с «ж» вернет код «59», на клавише с «4» тоже получился код 59. У символов в разных регистрах, например «ж» и «Ж» будут разные коды. У меня получились 166 и 134 соответственно. Интересно, что стандартное преобразование «(char)key» превратило эти коды в совершенно другие символы.

где взять код для игры. 24b4d4294206394df6d4f4f38450346e. где взять код для игры фото. где взять код для игры-24b4d4294206394df6d4f4f38450346e. картинка где взять код для игры. картинка 24b4d4294206394df6d4f4f38450346e. Объясните пожалуйста, почему я никогда не узнаю исходный код какой-нибудь игры пока разработчики его сами не выложат в открытый доступ или хакеры его не сольют?Обработка событий клавиатуры conio.h где взять код для игры. d5b0e865a5a429135b2ecba315521b69. где взять код для игры фото. где взять код для игры-d5b0e865a5a429135b2ecba315521b69. картинка где взять код для игры. картинка d5b0e865a5a429135b2ecba315521b69. Объясните пожалуйста, почему я никогда не узнаю исходный код какой-нибудь игры пока разработчики его сами не выложат в открытый доступ или хакеры его не сольют?Результат запуска обработки событий с помощью conio.h

Запуск периодических событий по таймеру

Как вы можете заметить, если просто отпустить программу в свободный полет, то она будет очень часто обращаться к списку событий. На моем компьютере получается несколько десятков раз за каждую миллисекунду. Само по себе это хорошо, т.к. позволяет оперативно реагировать на все действия игрока. Однако если мир будет меняться с такой же скоростью, то игрок никак не сможет поспеть за ним. Есть несколько способов контролировать период обновления мира. Я выбрал вариант без подключения дополнительных библиотек. Основная идея в том, чтобы постоянно смотреть на время, а обновление мира запускать каждые несколько секунд. Раз уж я докопал до ручной реализации event-loop, то изобрести велосипед с реализацией задержки в рамках выбранной архитектуры не составит труда.

Конкретная реализация нагуглилась с первого запроса «windows.h time milliseconds». https://stackoverflow.com/questions/17008026/windows-how-to-get-the-current-time-in-milliseconds-in-c Для очистки совести я еще попробовал поискать «cpp thread sleep» и «cpp sleep». Первый вариант получился слишком сложный, а второй недостаточно точный.

Существует несколько способов получить текущее время:

С помощью GetSystemTime из windows.h

С помощью std::chrono

Сразу говорю, второй вариант получается проще. Но я сначала пошел первым путем, а потом было жалко удалять это из черновика. Плохой пример тоже пример, поэтому смотрите.

Получение текущего времени Windows API

где взять код для игры. 2c67f4306bc8c24111243bb24c38afe7. где взять код для игры фото. где взять код для игры-2c67f4306bc8c24111243bb24c38afe7. картинка где взять код для игры. картинка 2c67f4306bc8c24111243bb24c38afe7. Объясните пожалуйста, почему я никогда не узнаю исходный код какой-нибудь игры пока разработчики его сами не выложат в открытый доступ или хакеры его не сольют?

Сделать хитрое сравнение.

Первый вариант может решить проблему только если я воспроизведу вычисление настоящего unix-timestamp, а мне лень. Например там будет сложность с количеством дней в месяце. Поэтому я сделаю менее точную версию, где «начало эпохи» будет в начале текущего месяца.

Код получается вот таким

где взять код для игры. 89ebf58d23f3dd1dd4be2cce0a3d2103. где взять код для игры фото. где взять код для игры-89ebf58d23f3dd1dd4be2cce0a3d2103. картинка где взять код для игры. картинка 89ebf58d23f3dd1dd4be2cce0a3d2103. Объясните пожалуйста, почему я никогда не узнаю исходный код какой-нибудь игры пока разработчики его сами не выложат в открытый доступ или хакеры его не сольют?Получение текущей даты Windows API

При запуске получается примерно такой вывод:

где взять код для игры. 4c2b7851920f988727b6c5bc7404f6d1. где взять код для игры фото. где взять код для игры-4c2b7851920f988727b6c5bc7404f6d1. картинка где взять код для игры. картинка 4c2b7851920f988727b6c5bc7404f6d1. Объясните пожалуйста, почему я никогда не узнаю исходный код какой-нибудь игры пока разработчики его сами не выложат в открытый доступ или хакеры его не сольют?Результат получения времени из Windows API

Теперь добавляю дополнительную переменную для хранения времени предыдущего обновления (prevTime) и периода между обновлениями (delay).

где взять код для игры. cdcb101ee4727f9794369360a858ef76. где взять код для игры фото. где взять код для игры-cdcb101ee4727f9794369360a858ef76. картинка где взять код для игры. картинка cdcb101ee4727f9794369360a858ef76. Объясните пожалуйста, почему я никогда не узнаю исходный код какой-нибудь игры пока разработчики его сами не выложат в открытый доступ или хакеры его не сольют?

Каждую итерацию цикла текущее время сравнивается со временем последнего обновления. Если разница больше задержки, то выполняется обновление. Дополнительно реализована функция для предупреждения перехода через ноль.

где взять код для игры. b3f79ae5b1cb1cc979c1310b385183e0. где взять код для игры фото. где взять код для игры-b3f79ae5b1cb1cc979c1310b385183e0. картинка где взять код для игры. картинка b3f79ae5b1cb1cc979c1310b385183e0. Объясните пожалуйста, почему я никогда не узнаю исходный код какой-нибудь игры пока разработчики его сами не выложат в открытый доступ или хакеры его не сольют?

При запуске получается примерно такой вывод.

где взять код для игры. d011b06f8ee804b98aee7713cf2a0f10. где взять код для игры фото. где взять код для игры-d011b06f8ee804b98aee7713cf2a0f10. картинка где взять код для игры. картинка d011b06f8ee804b98aee7713cf2a0f10. Объясните пожалуйста, почему я никогда не узнаю исходный код какой-нибудь игры пока разработчики его сами не выложат в открытый доступ или хакеры его не сольют?

Таким образом команда вывода слова «tick» будет выполняться раз в 300 миллисекунд. После нее нужно помещать логику будущей игры.

Получение текущего времени std::chrono

Реализация с помощью std::chrono получилась значительно проще. Но в ней используется непривычное для обычных людей запись времени. Там нет количества часов с начала дня, минут с начала часа и секунд с начала минуты. С помощью std::chrono можно получить количество миллисекунд с «начала эпохи». То есть с 1 января 1970 года. Это получается огромное целое число. Например 1610827417491. В отличие от «количества миллисекунд с начала секунды», это число всегда увеличивается. Поэтому не возникнет необходимости беспокоиться о переполнении часов.

В этом варианте я также использовал другой способ сравнения времени. На одно арифметическое действие в цикле меньше. Мелочь, а приятно.

где взять код для игры. 8ab2b3017d3277634888311814edcc73. где взять код для игры фото. где взять код для игры-8ab2b3017d3277634888311814edcc73. картинка где взять код для игры. картинка 8ab2b3017d3277634888311814edcc73. Объясните пожалуйста, почему я никогда не узнаю исходный код какой-нибудь игры пока разработчики его сами не выложат в открытый доступ или хакеры его не сольют?Получение текущего времени std::chrono

Константа PRIu64 нужна для форматированного вывода значения типа uint64_t с помощью printf. Для её использования нужно подключить inttypes.h Хотелось бы, конечно, не подключать лишних библиотек, но времени на обход именно этой библиотеки у меня не было.

Вывод получился вот таким

где взять код для игры. 45e434c5f28381884f134c1b66971558. где взять код для игры фото. где взять код для игры-45e434c5f28381884f134c1b66971558. картинка где взять код для игры. картинка 45e434c5f28381884f134c1b66971558. Объясните пожалуйста, почему я никогда не узнаю исходный код какой-нибудь игры пока разработчики его сами не выложат в открытый доступ или хакеры его не сольют?Вывод от получения текущего времени std::chrono

Что с этим можно сделать? Навскидку мне в голову пришло:

Симуляция гравитации в платформере. Каждые Х миллисекунд персонаж должен падать на 1 символ.

Полет пуль. Каждые Х миллисекунд передвинь пулю по направлению выстрела.

Движение змейки. Каждые Х миллисекунд передвинь сегменты змейки на один символ от головы.

где взять код для игры. image loader. где взять код для игры фото. где взять код для игры-image loader. картинка где взять код для игры. картинка image loader. Объясните пожалуйста, почему я никогда не узнаю исходный код какой-нибудь игры пока разработчики его сами не выложат в открытый доступ или хакеры его не сольют?

На картинке ниже вывод, который получается в такой программе время. Обратите внимание на чередование фраз «Each 225» и «Each 300».

где взять код для игры. image loader. где взять код для игры фото. где взять код для игры-image loader. картинка где взять код для игры. картинка image loader. Объясните пожалуйста, почему я никогда не узнаю исходный код какой-нибудь игры пока разработчики его сами не выложат в открытый доступ или хакеры его не сольют?

Генератор случайных чисел

Если немного копнуть в алгоритм генераторов случайных чисел, то можно обнаружить, что они не такие уж случайные. Поэтому используют более точный термин Генератор псевдо-случайных чисел или ГПСЧ.

По запросу «с++ rand» и «cpp rand» можно найти довольно много материалов. Например обширную статью на русском https://en.cppreference.com/w/cpp/numeric/random/rand и чуть более сухую на английском https://en.cppreference.com/w/cpp/numeric/random/rand

Вкратце перескажу основные тезисы:

Функция rand возвращает случайное число от 0 до RAND_MAX. Значение RAND_MAX зависит от библиотеки, но должно быть не менее 32767.

Если просто вызывать функцию rand, то при разных запусках, последовательность случайных чисел будет одинаковой.

Чтобы последовательность была каждый раз разной, нужно применить функцию srand.

Я от себя добавлю, что аргумент функции srand еще называют зерном (или «сидом» от слова seed). Вы подобное видели во многих играх при создании мира.

Примеры начальных значений для ГПСЧ

Если зерно мира заполнять одним и тем же значением, то получатся одинаковые последовательности случайных значений. В играх получатся одинаковые миры. Вот пример использования ГСПЧ с постоянным значением зерна.

где взять код для игры. image loader. где взять код для игры фото. где взять код для игры-image loader. картинка где взять код для игры. картинка image loader. Объясните пожалуйста, почему я никогда не узнаю исходный код какой-нибудь игры пока разработчики его сами не выложат в открытый доступ или хакеры его не сольют?

При запуске у меня появляется фраза «first is 440 second is 19053». Независимо от количества запусков получаются одни и те же числа. У вас могут получиться другие числа, но от запуска к запуску они должны быть одинаковы.

Чтобы последовательность менялась от запуска к запуску нужно передавать такое зерно, которое будет всегда разное. Что у нас не повторяется при запуске одной и той же программы раз за разом?

где взять код для игры. bf06b9d6dcabdbceddcc236d12662954. где взять код для игры фото. где взять код для игры-bf06b9d6dcabdbceddcc236d12662954. картинка где взять код для игры. картинка bf06b9d6dcabdbceddcc236d12662954. Объясните пожалуйста, почему я никогда не узнаю исходный код какой-нибудь игры пока разработчики его сами не выложат в открытый доступ или хакеры его не сольют?Инициализация зерна случайности с помощью std::chrono

Я варварски сконвертировал uion64_t в int, но этого оказалось достаточно.

Следующая проблема в том, что числа получаются огромные. Повторюсь, что rand возвращает число от 0 до RAND_MAX, который у меня равен 0x7fff. В десятичной системе счисления диапазон случайных чисел получается от 0 до 32767.

Вы когда-нибудь задумывались, а почему остаток от деления нам действительно помогает? Не получится ли такого, что какое-то число будет встречаться чаще других?

Строгое математическое доказательство будет чрезмерным для этой статьи. Поэтому постараюсь объяснить «на пальцах».

Как вы можете заметить, диапазон от 0 до 14 разделился на несколько отрезков от 0 до 3. Числа в правом столбце возрастают так же равномерно, как и в левом. Точно такая же закономерность прослеживается и на диапазоне от 0 до 32767. Функция rand() может вернуть каждое число «из левого столбца» с равной вероятностью. После нахождения остатка от деления мы получим соответствующее число из правого столбца.

Обратите внимание, что последний диапазон «от 0 до 3» в правом столбце не успел закончиться. Если числа в левом диапазоне будут выбираться с равной вероятностью, то числа 0, 1, 2 из правого столбца будут появляться чаще, чем число 3. То же самое будет и на полном масштабе, если 32767 не будет делиться нацело на выбранное вами ограничение. Впрочем, исходный диапазон рандома достаточно велик, чтобы мы не заметили этот небольшой недостаток. В документации на cppreference в формуле выбора числа есть попытка компенсировать его делением на «((RAND_MAX + 1u)/6)».

Как уже говорилось выше, рандом возвращает числа от 0 до ограничения. Проблема в том, что при написании игры нужно использовать числа не от 0, а например от 10 до 20. В реализации std::rand приходится упражняться со сложением и вычитанием. К счастью, я нашел ссылку на статью с описанием синтаксиса, который был добавлен в стандарт C++ от 2011 года. https://en.cppreference.com/w/cpp/numeric/random/uniformintdistribution В нем есть красивый способ описать рандом в нужном диапазоне. Немножко оформления и можно просто получать случайные числа в нужном диапазоне.

Подробнее о Вихре Мерсенна можно почитать на Википедии https://ru.wikipedia.org/wiki/%D0%92%D0%B8%D1%85%D1%80%D1%8C_%D0%9C%D0%B5%D1%80%D1%81%D0%B5%D0%BD%D0%BD%D0%B0

Меня такая находка очень порадовала. Пора переходить в туториалах для новичков на стандарт C++ хотя бы десятилетней давности. Этот фрагмент кода я специально для вас оформил текстом, который можно скопировать.

Изменение размера консоли

По умолчанию у меня в консоли помещается 80 символов в высоту и 50 в ширину. Это примерно треть моего экрана, поэтому захотелось увеличить количество символов в строке консоли хотя бы до 200.

Изменение размера окна консоли тоже оказалось задачкой с подвохом. Первый запрос был тривиальным «c++ change size of console window». Первый ответ на него подробно объяснял как сделать это с помощью настроек окна консоли на уровне операционной системы. То есть не из самой игры, а со стороны пользователя. Прикладывать эту инструкцию к игре я посчитал неправильным. Нужен способ сделать это из самой программы. Второй и последующие ответы описывали изменение размера окна консоли с помощью функции MoveWindow. Фактическое количество текста при этом не менялось. Если окно становилось слишком маленьким, то появлялись полосы прокрутки.

На тот момент я не знал точно, какие размеры стандартные и что я могу туда поставить. Поэтому указал 20 на 20. Для проверки размеров окна я также вывел прямоугольник из цифр от 0 до 9 шириной 20 на 20. Получился вот такой код:

где взять код для игры. 24aaf24cf0d6be91a9527e81b3fc1b86. где взять код для игры фото. где взять код для игры-24aaf24cf0d6be91a9527e81b3fc1b86. картинка где взять код для игры. картинка 24aaf24cf0d6be91a9527e81b3fc1b86. Объясните пожалуйста, почему я никогда не узнаю исходный код какой-нибудь игры пока разработчики его сами не выложат в открытый доступ или хакеры его не сольют?Заполнение экрана символами и изменение размера консоли

Вывод получился вот таким

где взять код для игры. 3983e432d496c36f3e71a5fe1ab69ab7. где взять код для игры фото. где взять код для игры-3983e432d496c36f3e71a5fe1ab69ab7. картинка где взять код для игры. картинка 3983e432d496c36f3e71a5fe1ab69ab7. Объясните пожалуйста, почему я никогда не узнаю исходный код какой-нибудь игры пока разработчики его сами не выложат в открытый доступ или хакеры его не сольют?

Поскольку это работа на уровне WinAPI, в результате получился код ошибки. Я в основном работаю с java стеком и обычно вижу стектрейсы и тексты исключений. Несмотря на это, принцип решения проблемы не изменился. Для расшифровки кода ошибки нужно воспользоваться официальной документацией. Она легко ищется запросом «getlasterror error codes». Кодов ошибок описано около девяти тысяч на нескольких страницах. Для моего случая подойдет первая страница https://docs.microsoft.com/en-us/windows/win32/debug/system-error-codes—0-499-

Ошибка гласит ERROR-INVALID-PARAMETER 87 (0x57) The parameter is incorrect.

Маловато объяснений. Тогда я проверил как другие пишут этот код. Запрос «SetConsoleScreenBufferSize incorrect argument» привел меня вот на этот вопрос на SO https://stackoverflow.com/questions/12900713/reducing-console-size

В ключевых аспектах код ответа был похож на мой. Но в нем содержалось важное дополнение «If you call SetConsoleScreenBufferSize with illegal value in COORDS (e.g. too little height/width) then you get an error, usually 87 ‘invalid argument’.»

Исходный код был видоизменен вот так:

где взять код для игры. f48ed71134f37a1898fe277621687c71. где взять код для игры фото. где взять код для игры-f48ed71134f37a1898fe277621687c71. картинка где взять код для игры. картинка f48ed71134f37a1898fe277621687c71. Объясните пожалуйста, почему я никогда не узнаю исходный код какой-нибудь игры пока разработчики его сами не выложат в открытый доступ или хакеры его не сольют?

Вывод при этом получился таким

где взять код для игры. 4e23e03e95cade0ae55eab0a7714fdd8. где взять код для игры фото. где взять код для игры-4e23e03e95cade0ae55eab0a7714fdd8. картинка где взять код для игры. картинка 4e23e03e95cade0ae55eab0a7714fdd8. Объясните пожалуйста, почему я никогда не узнаю исходный код какой-нибудь игры пока разработчики его сами не выложат в открытый доступ или хакеры его не сольют?

Ускорение вывода текста

Запустив программу для заполнения большого экрана символами, я обнаружил, что текст пишется в консоль очень медленно. Заполнение символами экрана 200 на 80 заметно человеческому глазу. За одну секунду получится обновить экран лишь 1-2 раза. Это вряд ли связано с производительностью компьютера. Интуиция подсказывает, что это искусственное ограничение. При решении этой проблемы у меня было два направления поиска:

Как быстро написать много текста?

Как обновить только тот фрагмент экрана, который действительно менялся?

Сначала я поискал «cpp console reduce delay between screen updates». Практически все ссылки вели на советы по добавлению паузы, что мне совершенно не интересно. Только один ответ в выдаче говорил что-либо об ускорении вывода https://stackoverflow.com/questions/26376094/c-writing-to-console-without-delays. В нем предлагается подготовить большой буфер в памяти и вывести его одной командой.

Затем я поискал «windows.h write lot of text without animation» и нашел вот такой вопрос с очень любопытным ответом. https://stackoverflow.com/questions/34842526/update-console-without-flickering-c

Автор вопроса и автор ответа разговаривают в контексте создания консольной игры. Вместо полной очистки и полного заполнения экрана в ответе предлагается:

Переставить курсор и писать новый текст поверх старого без предварительной очистки экрана.

Переписывать фрагменты, а не отдельные буквы.

Переписывать отдельные буквы на экране.

Использовать два буфера и писать на экран только разницу.

Обратите внимание, в ответе на вопрос есть еще пример настройки цвета текста в консоли. У меня, к сожалению, не хватило времени воспроизвести этот прием.

Перестановка курсора

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

За основу был взят код из главы «Изменение размера консоли».

Для своего удобства я реализовал функцию заполнения структуры нужными координатами.

Функция подготовки структуры с координатами

Для перестановки курсора достаточно вызвать функцию SetConsoleCursorPosition и передать ей в качестве аргументов поток вывода и структуру с координатами желаемой позиции курсора.

Вызов функции SetConsoleCursorPosition для перестановки курсора

Как я уже говорил, это улучшило ситуацию, но проблему полностью не решило. Поэтому я решил раскопать поглубже.

Вывод готовых фрагментов текста

Вывод текста фрагментами

В примерах еще часто использовался std::cout.flush(), который тащит за собой подключение iostream. Мне не хотелось использовать дополнительную библиотеку. Наверняка аналог есть и в stdio, который уже подключен. Мой запрос для поиска был «stdio flush output». Две ссылки на Stackoverflow указывают на fflush

Функция fflush вызывается с аргументом stdout. Я минут 10 искал как правильно заполнить переменную stdout, а оказалось она просто доступна из глобальной области видимости.

Настройка буферизации stdio.h

Настройка буфера вывода с помощью stdio.h

Измерение производительности

Тут я осознал, что не в состоянии сравнить производительность разных вариантов «на глаз». Поэтому вкрутил измерение времени до и после обновления экрана. Напишу тут порядок цифр, потому что значения с точностью до микросекунд не существенны для сравнения. Код практически полностью списал из ответа к этому вопросу https://stackoverflow.com/a/21856299

Функция получения времени с точностью до микросекунд

Измерил количество микросекунд без явного указания буфера. Три запуска, три числа: 8930000 8880000 9220000.

с размером буфера 1/16 от 740000 до 750000 микросекунд

с размером буфера 1/8 от 40000 до 39000 микросекунд

с размером буфера 1/4 от 18000 до 19000 микросекунд

с размером буфера 1/2 от 12000 до 13000 микросекунд

с размером буфера равным ширине консоли от 90000 до 10000.

Во всех этих случаях наблюдается мигание строк на экране размером с буфер. То есть при буфере 1/4, мигают фрагменты в четверть строки. С буфером равным ширине консоли получается очень большой разброс, причем без промежуточных значений. либо за 10000, либо за 90000. При этом мигает так, как будто буфер половина. redraw настройка буфера библиотеки.PNG

Велосипедный вариант с заполнением массива и выводом его на экран получился такой же, как с размером буфера равным ширине консоли. Были цифры 90000 и 10000 без промежуточных значений. При этом для создания буфера меньшего размера пришлось бы значительно усложнить реализацию. redraw велосипедный буфер.PNG

Чтобы применить технику двойной буферизации, нужно чтобы на экране что-нибудь менялось. При этом меняться должен не весь экран, а только некоторые части.

Заключение

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

Источник

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *