Как вы можете поместить все изображения из игры в 1 файл?

67

Я только что закончил основную RPG-игру, написанную на C ++ SFML, я приложил немало усилий и хотел бы ее распространить, однако натолкнулся на небольшую проблему.

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

Что ж, это то, чего я пытаюсь достичь: я надеюсь упаковать все изображения в 1 файл (возможно, также и в TXT-файлы), а затем прочитать его или легко добавить к нему.

Bugster
источник
Я видел код, где все изображения были упакованы в строку в коде. Но это было сделано из-за требований. (Это был Java-конкурс размером 64 КБ)
Омар Кохеджи,
Извините, это был 4Kb Java-конкурс Не 64Кб ​​один.
Омар Кохеджи

Ответы:

62

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

  • хранить каждый файл данных как отдельный файл
  • хранить каждый файл данных в произвольном формате архива

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

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

Если вы не будете всегда загружать все файлы из архива, TAR / GZ может быть не очень хорошей идеей, потому что вы не можете извлекать определенные файлы так, как вам нужно. По этой причине во многих играх используются ZIP-архивы, которые позволяют извлекать отдельные файлы по мере необходимости (хорошим примером является Quake 3, файлы PK3 которого представляют собой не что иное, как ZIP-файлы с другим расширением).

РЕДАКТИРОВАТЬ: «Скрыть» структуру папок игры и «Сохранить» только исполняемые файлы

Другое решение часто используется для «скрытия» файлов игры в структуре папок. Сохраните только свои исполняемые файлы и, возможно, файл readme в главном каталоге и переместите файлы игры в подпапку с именем «data» или другой связанной с ней.

РЕДАКТИРОВАТЬ: Gamedev Tuts Plus есть хороший ресурс

РЕДАКТИРОВАТЬ: библиотека

Одно из возможных решений libarchive, которое представляет собой архивную библиотеку, которая будет обрабатывать извлечение файлов из архива, такого как ZIP-файл. Он даже позволяет назначить извлеченный файл стандартному указателю FILE, что делает взаимодействие с другими библиотеками потенциально более простым.

РЕДАКТИРОВАТЬ: файлы формата ZIP с альтернативным расширением

Здесь мне нравится @Joachim Sauer Комментарий

Использование файлов в формате ZIP с альтернативными расширениями имеет большую традицию и вне игр: Java это делает , формат OpenDocument (он же формат OpenOffice / LibreOffice) , даже Office Open XML (он же «новый» формат Microsoft Office) это делает .

Махбубур Р Ааман
источник
2
Да, Thief / SystemShock2 использовал файлы .zip, переименованные во что-то еще. В Java вы можете использовать что-то вроде TrueZip для доступа к файлам в zips, как если бы они были файлами в папках, я думаю, что есть аналогичные библиотеки для C ++.
Ник
18
Использование файлов в формате ZIP с альтернативными расширениями имеет большую традицию и вне игр: Java это делает , формат OpenDocument (он же формат OpenOffice / LibreOffice) , даже Office Open XML (он же «новый» формат Microsoft Office) делает это ,
Иоахим Зауэр
5
@Svish. В зависимости от платформы объем дискового пространства, занимаемого большим количеством маленьких файлов, может быть значительно больше, чем объем, занимаемый одним большим файлом, даже если этот большой файл вообще не сжимается ( .tarнапример). Это связано с тем, как данные физически хранятся на диске.
TRiG
1
Ах, это правда. Хотя не должно быть много, если не много , но в этом случае это действительно может накапливаться. Я могу себе представить, что установка и удаление также требует большого количества маленьких файлов.
Свиш
2
Слегка связанный с комментарием Килотана, вот пост Джонатана Блоу на dev-блоге The Witness об использовании архивов и о том, как они взаимодействуют с механизмом исправлений Steam. «Witness упаковывает большую часть своих данных в один файл объемом 2 гигабайта, хранящийся в формате .zip. Перед загрузкой исходной версии в Steam я принял меры предосторожности, чтобы минимизировать размеры патчей, или, как мне показалось, [...] (представьте себе, что файлы хранятся в случайном порядке: вероятно, каждый патч включает в себя каждый игрок, заново загружающий всю игру!) »
Эрик
39

Другим решением, часто используемым для «скрытия» файлов игры, является структура папок. Сохраните только свои исполняемые файлы и, возможно, файл readme в главном каталоге и переместите файлы игры в подпапку «data». Я не думаю, что это очень редко случается. Многие игры, которые я знаю, хранят свой контент таким образом.

Том Ван Грин
источник
8
+1 Если дисковое пространство или защита не проблема, это самое простое решение.
Лоран Кувиду
1
+1 потому что другой парень сказал +1. Не ошибаешься, а? (Шутка в сторону, отличный ответ.)
Jcora
Это, на мой взгляд, идеальный выбор. Если файловая система не может справиться с этим эффективно, файловая система сломана, и вы должны опираться на производителя ОС, чтобы улучшить его.
Всезнающий
3
@ Omnifarious Это не всегда так, например, при чтении с оптического диска, даже с идеальной файловой системой, обычно упаковывают файлы в порядке загрузки, чтобы предотвратить чрезмерный поиск (ускорение может быть довольно неожиданным). Но это совсем другая история для жестких дисков, и я склонен думать, что OP в этом случае.
Лоран Кувиду
3
@ Mr.Beast Вы пропустили мою точку зрения. Я говорю об оптических дисках. Я работал в студии, где работа одного программиста была занята полный рабочий день, чтобы обеспечить максимально эффективную упаковку файлов на DVD, чтобы получить наилучшее время загрузки. Я уверен, что он был бы рад узнать, что он мог просто положиться на файловую систему DVD;)
Лоран Кувиду
22

Мне действительно нравится PhysFS для этого. Это позволяет получить доступ к папкам или zip-архивам с одним и тем же кодом. Это хорошо работает на всех этапах жизни игр.

  1. Во время разработки : доступ к ресурсам напрямую из иерархии папок. Таким образом, сжатые архивы не мешают, и вы можете быстро выполнять итерации.
  2. Первоначальное развертывание : заархивируйте свои ресурсы для простого развертывания / быстрой установки. Код не нужно менять. Просто укажите PhysFS на zip вместо папки.
  3. Обновления / Моддинг : PhysFS может загружать несколько zip-архивов, где ресурсы одного переопределяют другой. Обновления могут быть такими же простыми, как новый zip, только с измененными файлами. Аналогично для моддинга.

Обновить:

Я использовал учебник, включенный в исходный код, и документацию по Doxygen для изучения PhysFS. API действительно довольно прост, вы потратите больше времени на изучение загрузки изображений в SFML через буферы памяти, а не по пути к файлу.

deft_code
источник
4
Я использую PhysFS для своего текущего проекта, и мне это нравится. Мне не всегда нужно восстанавливать файл архива контента; Я могу просто сбросить обновленную версию в пути поиска и БАМ! Оно работает.
Зак Человек
После некоторых ответов я решил, что пойду с PhysFS. Не могли бы вы порекомендовать хороший учебник? :)
Bugster
12

Я бы предложил использовать ZIP-файл. Это повсеместный формат, и вы найдете готовые библиотеки, которые позволяют загружать файлы из ZIP-файла. Быстрый поиск в Google даже показал zip-загрузчик sfml .

bummzack
источник
3

Ну, вы могли бы обмануть, как они упоминали :) Вы можете сделать спрайт-лист из изображений, в настоящее время нет необходимости застегивать его, если это не сэкономит массу места. После того, как вы создадите спрайт-лист или несколько спрайт-листов из изображений, вы можете просто переименовать их расширения. Большинство геймеров не будут проверять, и почему бы не оставить этот вариант для художников, которые могут захотеть изменить вашу игру в будущем? Таким образом, они также могут создать спрайт-лист, переименовать его расширение и начать работу.

С текстовыми файлами я бы скромно предложил вам преобразовать эти данные в двоичную форму. Я почти уверен, что вы найдете простой способ сделать это. Например, если вы используете только AZ, az и 0-9, вы можете использовать 6 бит для представления каждого символа, что несколько защитит ваш защищенный авторским правом материал, это также не позволит другим редактировать карты. Вы всегда можете добавить конвертер карт, если хотите. Молния вполне разумна для текста, хотя.

wolfdawn
источник
Преобразование в двоичный код - это хороший совет, но не для защиты - его будет проще анализировать и быстрее загружать. Предложил бы это как шаг предварительной обработки, но это не по теме для вопроса.
Максимус Минимус
Ну, я предполагаю, что если он хочет защитить его более эффективно, он может попытаться зашифровать его с помощью RSA или аналогичного алгоритма (в этом нет необходимости). Я сомневаюсь, что кто-либо сделает несанкционированное использование файлов карты из инди-игры, если она находится внутри двоичного файла. Кажется, просто не стоит тратить время на анализ нашего анализа. Текстовые файлы просто полностью уязвимы и, как вы предложили, что-то неэффективное для хранения данных.
волчий рассвет
3
На жестких дисках загрузка одного zip-файла происходит быстрее, чем большого количества маленьких файлов, поскольку на физическом диске выполняются менее дорогие случайные операции поиска. Бинарный файл для маленькой игры может быть отображен в память и работать «волшебно», практически не требуя анализа.
Лиосан
@Liosan Возможно, вы неправильно поняли, что я имел в виду, или я вас неправильно понял. Я сказал, что двоичный файл лучше подходит для хранения данных, и что другие разработчики игр вряд ли захотят научиться анализировать код бинарной карты, если он не задокументирован и не поощряется для моддинга. цели. Поэтому он предлагает некоторую элементарную защиту текстовых файлов.
волчий рассвет
2

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

Эдмо Фрейтас
источник
После получения нескольких ссылок на создание таблицы спрайтов я подумал о рефакторинге, чтобы уменьшить количество изображений. Спасибо
Bugster
2

Для этого я бы лично выбрал маршрут для двоичного файла. Это то, что я делаю сам сейчас все время, это не так сложно, как может показаться, и это также обеспечивает уровень запутанности для ваших файлов игровых ресурсов. Я написал небольшую вступительную статью об этом Gamedev не так давно, если вам интересно:

http://gamedev.tutsplus.com/tutorials/implementation/create-custom-binary-file-formats-for-your-games-data/

Спрайт-листы - это совершенно другой предмет, но они являются нормой для большинства игр :)

Си Робертсон
источник
1

Другой метод, который вы можете использовать:

Бесплатная версия XnView предоставляет функцию под названием « Strip of Images» (SHIFT + A), которая позволяет создавать sprite-collections.

Это минимизирует доступ к файлам и особенно важно для веб-приложений / игр, чтобы минимизировать количество HTTP-roundtrips.

Доступ к отдельным изображениям затем предоставляется через карты координат (например, определения css).

Лоренц Ло Зауэр
источник
0

Сначала вы должны написать все свое изображение / звук / и т.д. загрузка подпрограмм, использующих пользовательский API для доступа к архивным данным. Еще одним недостатком является то, что вы должны написать свою собственную утилиту архивирования для создания архивов в первую очередь. Если вы не будете всегда загружать все файлы из архива, TAR / GZ может быть не очень хорошей идеей, потому что вы не можете извлекать определенные файлы так, как вам нужно. По этой причине во многих играх используются ZIP-архивы, которые позволяют извлекать отдельные файлы по мере необходимости (хорошим примером является Quake 3, файлы PK3 которого представляют собой не что иное, как ZIP-файлы с другим расширением). http://zpp-library.sourceforge.net/


источник