Я пытаюсь сделать видеоигру с нуля, но я действительно новичок в этом и продолжаю сталкиваться с основными проблемами. Самое главное, как видеоигры хранят закадровую информацию? Что я имею в виду, как программа знает, что отображать дальше на экране? Или даже, если игрок меняет среду, как это изменение останется при следующей загрузке на экран?
Например, в New Super Mario Bros, если вы нажмете? заблокировать и затем выключить экран, и вернуться, он все еще остается ударом. Как эта информация хранится и затем выполняется при следующей загрузке блока? Почему он просто не сбрасывается?
game-design
architecture
software-engineering
game-mechanics
Всего несколько вопросов
источник
источник
Ответы:
Обычно вы должны отделять логическое состояние игровой среды от визуального представления.
Игрок может видеть только небольшую его часть на своем экране, но вы по-прежнему сохраняете состояние всего уровня в памяти и обычно также рассчитываете игровую механику для всего уровня. Когда ваш мир настолько огромен, что для этого потребуется слишком много оперативной памяти и / или процессора, вы можете приостановить удаленные области на жесткий диск.
Ваша подпрограмма рендеринга проверяет, какие части уровня в данный момент находятся на экране, а затем только рисует те. Все, что находится за кадром, не рисуется, но это не значит, что оно не обновляется.
источник
Вы идете в обратном направлении.
Вы начинаете с логического состояния вашей игры и моделируете это. Целое логическое состояние всего мира почти наверняка будет слишком большим, чтобы его можно было хранить в памяти сразу, поэтому вы разбиваете его на более мелкие части, которые можно загружать и сохранять независимо. Эти части часто называют кусками . Эти куски могут образовывать непрерывный мир, но они также могут быть отдельными уровнями / экземплярами. Терминология сильно варьируется в зависимости от жанра и техники, которую вы хотите использовать.
Затем вы загружаете те части, которые представляют интерес, то есть куски, которые находятся в непосредственной близости от игрока. Куски, которые находятся слишком далеко, сохраняются на диске / в постоянном хранилище и выгружаются из памяти.
И затем, в качестве последнего шага, вы определяете, что на самом деле видно, и создаете визуальное представление текущего состояния игры и отображаете его на экране.
Конечно, вы бы старались не перестраивать все визуальное представление каждый раз, а кэшировать его и использовать повторно, если у вас уже есть детали, которые уже созданы, но это основной принцип.
Это верно для любой программы, которая имеет вывод. Если вы пишете программу с обычным графическим интерфейсом, например, текстовым редактором, вы, скорее всего, смоделируете документ, а затем графический интерфейс определит состояние и видимые части документа и отобразит его на экране. Или заполните поля формы соответствующим образом, или иначе.
Основная суть заключается в следующем: сначала подумайте, где и как вы храните данные (вероятно, вместе с тем, как их представлять). Почти каждая программа имеет дело с хранением данных. Лишь в немногих случаях вы не сохраняете никаких данных.
источник
Как уже говорили другие, вы держите карту (например, в массиве) и рисуете видимую ее часть на экране, а не читаете обратно с экрана.
Но в некоторых старых системах вы буквально держите данные вне экрана. Скажем, для видеопамяти размером 320х200 будет, скажем, 400x300 пикселей видеопамяти, и вы определите в ней область просмотра («начинаются с X = 10 Y = 30»). Таким образом, вы можете прокручивать экран, просто настраивая регистр. Вам не нужно тратить сотни тысяч циклов, необходимых для перемещения байтов, вы просто меняете, где видеооборудование начинает их читать.
NES имеет это в сочетании с системой на основе плиток: http://wiki.nesdev.com/w/index.php/PPU_scrolling
NES никогда не создает полный образ в памяти, потому что у него недостаточно оперативной памяти. Вместо этого есть массив RAM, который определяет набор плиток шириной в два экрана. Один байт на вид плитки. Видеооборудование ищет координаты плитки и смещения X / Y, чтобы решить, какой пиксель должен появиться в любой точке.
источник
Что ж, если вы задаете такой вопрос, у вас будет долгий путь, чтобы добраться до того момента, когда вы сможете сделать игру. Но, доходя до сути вашего вопроса, программа может сохранить состояние множества различных вещей в переменных, которые находятся в бэкэнде вашей программы. Давайте посмотрим на пару примеров.
Mario Brothers (или аналогичный) сохраняет состояние уровня, на котором вы находитесь. Это может включать в себя то, как далеко вы продвинулись до своей смерти, был ли удар по блоку или нет. В некотором более объектно-ориентированном смысле игра просто говорит «будь блоком здесь», и блок существует. затем, когда вы нажимаете на блок, блок меняет свое собственное внутреннее состояние, говоря: «Я был поражен». Подобные данные могут храниться различными способами.
Ваш текстовый процессор сохраняет свои данные в структуре данных. Сейчас существует множество таких и многих способов их реализации, но, вероятно, используется некоторая форма дерева. В дереве у вас есть хотя бы один узел. Все, что добавлено до того, как оно уходит влево. Все, что добавлено после него, идет вправо. После добавления трех узлов у вас есть два из них, висящие на среднем узле. И дерево может вырасти еще больше с новыми частями, добавленными куда угодно, и дерево восстановит себя. Или подумайте о шутерах, где ваш враг бродит. У каждого из них есть переменные, которые отслеживают их местоположение, жизнь и т. Д., Поэтому, когда вы пораните один, он будет помнить, что это было больно.
Все эти вещи требуют знания структур данных. Это выходит за рамки того, что вы видите на экране. Я бы посоветовал прочитать о массивах, списках, хэшах (иногда называемых словарями или картами), а затем вернуться к вашей проблеме.
Вот несколько хороших исходных материалов:
источник
В некоторой степени это зависит от того, как 3D отображается. Например, OpenGL автоматически отбраковывает геометрию за пределами диапазона -1,0, +1,0 в пространстве экрана XY (Z более сложный, но похожий). Отобранная геометрия никогда не генерирует фрагменты (приблизительно пиксели) и, следовательно, никогда не превращается в фактические изображения, несмотря на то, что отправляется в систему для визуализации. В любом случае невозможно записать в пространство за пределами окна рендеринга (если все работает как надо).
В некоторых случаях достаточно полагаться на это поведение как на оптимизацию. Тем не менее, вам все равно придется пройти все свои игровые данные, по крайней мере, через одну стадию рендеринга (вершинные шейдеры), прежде чем видеокарта сможет узнать, что видно. В чем-то вроде, скажем, Скайрима, это было бы непрактично. Вам нужно не только отправить каждую вершину в мире через конвейер рендеринга, но и загрузить каждую вершину в системную / видеопамять. Это неэффективно, если вообще возможно.
Таким образом, во многих играх используется отбор на основе процессора. Как правило, они реализуют какую-то систему LOD (уровень детализации), где качество и наличие активов зависит от того, насколько важно, чтобы они оценивались в данном контексте. Пирамидальная сетка может быть приемлемым приближением для горы, если вы находитесь в 50 милях от нее. Если вы его вообще не видите (например, он заблокирован другими горами), нет необходимости даже загружать его. Существует ряд более сложных методов для этого, которые, по моему мнению, не имеют прямого отношения к глубине, запрошенной этим вопросом, но посмотрите на тесселяцию для одного из самых распространенных примеров.
Реальная суть этого в том, что визуальные эффекты являются лишь продуктом игры. Фактические данные не имеют непосредственного отношения к тому, что вы видите или не видите большую часть времени, и данные фильтруются по различным этапам для удаления посторонней информации, прежде чем попасть в точку, где изображение выводится на экран. В зависимости от конструкции движка, визуальные эффекты могут быть чрезвычайно отделены от реальной игровой логики, поскольку возможно что-то вроде двухмерного и трехмерного интерфейса к одной и той же игре. Многие игровые движки даже могут работать без какой-либо производительности; иногда это используется для тестирования игрового ИИ.
Вот где все может быть сложно, хотя. В чем-то простом, например, в игре Mario, не слишком сложно вычислить движение всех врагов на уровне, даже если они не видны. В современных условиях то, что происходит за кадром, является серьезным вопросом. Если есть несколько целых городов NPC, как вы справляетесь с их поведением, когда они полностью отбракованы - например, когда игрок находится в другом городе? Вы действительно хотите вычислять сотни решений NPC по всей карте? Ответ обычно - нет, но точный подход к достижению цели может отличаться, и это может иметь некоторые последствия для игры.
Важно отметить, что именно так все и происходит сейчас . Сами старые игры Mario, скорее всего, были запрограммированы совершенно по-разному (я не могу сказать точные способы), учитывая экстремальные аппаратные ограничения в то время. Концепция 3D еще не существовала; однако сегодня почти все игры, даже полностью двумерные, используют 3D-рендеринг в той или иной форме, даже если они не знают, что это делают. Современное видеооборудование - это, прежде всего, 3D, а 2D-рендеринг (по крайней мере, когда он правильно использует аппаратное обеспечение) просто игнорирует 3-е измерение.
источник
Чтобы ответить на ваш вопрос: видеоигры сохраняют состояние игрового мира в некоторой абстрактной структуре данных, которая не имеет ничего общего с экраном. Затем он отображается на экране по мере необходимости (т.е. в зависимости от того, где находится игрок).
Игры, которые используют видеопамять напрямую для государственных целей, были примерно в 80-х годах в 8-битной, возможно, даже в 16-битной эре, но если вы не разрабатываете для этой платформы или для некоторого микроконтроллера, который вместо этого объединяет свою RAM в КБ ГБ, забудь об этом.
Тем не менее, вы, кажется, очень плохо знакомы со всем, что связано с программированием, иначе вопрос не возник бы. Я предлагаю идти по шагам, сначала программируя очень простые вещи; может быть что-то, что имеет только текстовый ввод / вывод (простые подсказки и все такое). Если честно, то время, когда я это делал, прошло около 30 лет, поэтому у меня нет действительно хороших ресурсов для вас, но ваша местная библиотека может быть лучше Интернета, чтобы дать вам действительно хорошее начало в программировании.
источник