Как видеоигры хранят информацию вне экрана?

16

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

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

Всего несколько вопросов
источник
24
Pedantry: В Super Mario Bros, если вы нажмете? заблокировать, а затем уйти с экрана, вы не можете вернуться - игра прокручивается только в одном направлении, и все трубы деформации являются однонаправленными.
Тревор Пауэлл
61
Когда вы читаете текстовый документ и прокручиваете его, удаляет ли ваш текстовый процессор начало документа?
Филипп
31
Монитор показывает окно в игровой мир. Мир существует за пределами вашего окна - вы просто его не видите.
Felsir
11
Гораздо более типичный вопрос программирования для новичков: «Как я могу отобразить мою информацию на экране?». Проработайте любое учебное пособие по программированию, и когда вы придете к этому вопросу, у вас уже должен быть ответ на ваш вопрос.
Питер
4
Интересно, в какой среде разработки вы работаете, когда держать вещи за пределами экрана звучит сложнее, чем выводить их на экран :) Или это чисто теоретический вопрос?
Луаан

Ответы:

59

Обычно вы должны отделять логическое состояние игровой среды от визуального представления.

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

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

Philipp
источник
37

Вы идете в обратном направлении.

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

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

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

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


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

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

Polygnome
источник
7
глыбы? Я бы назвал эти маленькие кусочки уровнями .
gbjbaanb
3
Это хорошо, за исключением того, что «вы разбиваете его на более мелкие части, которые можно загружать и сохранять независимо. Эти части часто называют кусками», что, по-видимому, характерно для игр с очень большими мирами. Во многих играх такого не нужно. Я не удивлюсь, если вы поместите в память все данные уровней для каждого когда-либо созданного 2D-скроллера.
user253751
3
@gbjbaanb «Уровень» - это устаревший термин, а «чанк» - гораздо более всеобъемлющее и четко различаемое понятие. Не все куски являются уровнями и не все уровни являются кусками.
Лилиенталь
3
Я думаю, что полезный способ думать об этом состоит в том, что технически возможно играть всю игру без визуализации одного пикселя, то есть вся игра отделена от визуального представления.
Натан К
1
@Lilienthal уверен, но я думаю, что уровень все еще широко распространен, и многие игры все еще имеют концепцию - я не уверен, что какая-либо из них выдает экран «загрузочного блока» при получении новой «арены», после чего игрок пересекает их. Следовательно, это может быть более понятно, особенно для ОП, который является новичком в играх, чем относительно технический термин, который он, возможно, никогда раньше не видел.
gbjbaanb
6

Как уже говорили другие, вы держите карту (например, в массиве) и рисуете видимую ее часть на экране, а не читаете обратно с экрана.

Но в некоторых старых системах вы буквально держите данные вне экрана. Скажем, для видеопамяти размером 320х200 будет, скажем, 400x300 пикселей видеопамяти, и вы определите в ней область просмотра («начинаются с X = 10 Y = 30»). Таким образом, вы можете прокручивать экран, просто настраивая регистр. Вам не нужно тратить сотни тысяч циклов, необходимых для перемещения байтов, вы просто меняете, где видеооборудование начинает их читать.

NES имеет это в сочетании с системой на основе плиток: http://wiki.nesdev.com/w/index.php/PPU_scrolling

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

pjc50
источник
6
Хотя это и правда, это деталь реализации - главный принцип по-прежнему заключается в том, что у вас есть логическое состояние и вы его визуализируете (и, как я уже говорил, кешируйте некоторые его части, уже подготовьте некоторые вещи, которые появятся в следующей точке зрения и т. Д.).
Полигном
2
@Polygnome Ну, я написал много игр, где экран был в состоянии игры. Удивительно, что вы можете сделать с 4 000 байтов VRAM! :)
Luaan
1

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

Mario Brothers (или аналогичный) сохраняет состояние уровня, на котором вы находитесь. Это может включать в себя то, как далеко вы продвинулись до своей смерти, был ли удар по блоку или нет. В некотором более объектно-ориентированном смысле игра просто говорит «будь блоком здесь», и блок существует. затем, когда вы нажимаете на блок, блок меняет свое собственное внутреннее состояние, говоря: «Я был поражен». Подобные данные могут храниться различными способами.

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

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

Вот несколько хороших исходных материалов:

BSD
источник
0

В некоторой степени это зависит от того, как 3D отображается. Например, OpenGL автоматически отбраковывает геометрию за пределами диапазона -1,0, +1,0 в пространстве экрана XY (Z более сложный, но похожий). Отобранная геометрия никогда не генерирует фрагменты (приблизительно пиксели) и, следовательно, никогда не превращается в фактические изображения, несмотря на то, что отправляется в систему для визуализации. В любом случае невозможно записать в пространство за пределами окна рендеринга (если все работает как надо).

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

Таким образом, во многих играх используется отбор на основе процессора. Как правило, они реализуют какую-то систему LOD (уровень детализации), где качество и наличие активов зависит от того, насколько важно, чтобы они оценивались в данном контексте. Пирамидальная сетка может быть приемлемым приближением для горы, если вы находитесь в 50 милях от нее. Если вы его вообще не видите (например, он заблокирован другими горами), нет необходимости даже загружать его. Существует ряд более сложных методов для этого, которые, по моему мнению, не имеют прямого отношения к глубине, запрошенной этим вопросом, но посмотрите на тесселяцию для одного из самых распространенных примеров.

Реальная суть этого в том, что визуальные эффекты являются лишь продуктом игры. Фактические данные не имеют непосредственного отношения к тому, что вы видите или не видите большую часть времени, и данные фильтруются по различным этапам для удаления посторонней информации, прежде чем попасть в точку, где изображение выводится на экран. В зависимости от конструкции движка, визуальные эффекты могут быть чрезвычайно отделены от реальной игровой логики, поскольку возможно что-то вроде двухмерного и трехмерного интерфейса к одной и той же игре. Многие игровые движки даже могут работать без какой-либо производительности; иногда это используется для тестирования игрового ИИ.

Вот где все может быть сложно, хотя. В чем-то простом, например, в игре Mario, не слишком сложно вычислить движение всех врагов на уровне, даже если они не видны. В современных условиях то, что происходит за кадром, является серьезным вопросом. Если есть несколько целых городов NPC, как вы справляетесь с их поведением, когда они полностью отбракованы - например, когда игрок находится в другом городе? Вы действительно хотите вычислять сотни решений NPC по всей карте? Ответ обычно - нет, но точный подход к достижению цели может отличаться, и это может иметь некоторые последствия для игры.

Важно отметить, что именно так все и происходит сейчас . Сами старые игры Mario, скорее всего, были запрограммированы совершенно по-разному (я не могу сказать точные способы), учитывая экстремальные аппаратные ограничения в то время. Концепция 3D еще не существовала; однако сегодня почти все игры, даже полностью двумерные, используют 3D-рендеринг в той или иной форме, даже если они не знают, что это делают. Современное видеооборудование - это, прежде всего, 3D, а 2D-рендеринг (по крайней мере, когда он правильно использует аппаратное обеспечение) просто игнорирует 3-е измерение.


источник
В дополнение к методам LoD, было бы хорошо добавить сценограф к этому ответу - где мир может храниться в памяти и «отбраковываться» процессором в зависимости от того, что находится внутри вида.
gbjbaanb
0

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

Игры, которые используют видеопамять напрямую для государственных целей, были примерно в 80-х годах в 8-битной, возможно, даже в 16-битной эре, но если вы не разрабатываете для этой платформы или для некоторого микроконтроллера, который вместо этого объединяет свою RAM в КБ ГБ, забудь об этом.

Тем не менее, вы, кажется, очень плохо знакомы со всем, что связано с программированием, иначе вопрос не возник бы. Я предлагаю идти по шагам, сначала программируя очень простые вещи; может быть что-то, что имеет только текстовый ввод / вывод (простые подсказки и все такое). Если честно, то время, когда я это делал, прошло около 30 лет, поэтому у меня нет действительно хороших ресурсов для вас, но ваша местная библиотека может быть лучше Интернета, чтобы дать вам действительно хорошее начало в программировании.

Anoe
источник