Como você pode colocar todas as imagens de um jogo em 1 arquivo?

67

Acabei de terminar um jogo básico de RPG escrito em C ++ SFML, dediquei muito esforço ao jogo e gostaria de distribuí-lo, no entanto, encontrei um pequeno problema.

O problema é que tenho mais de 200 imagens e arquivos de mapeamento (são arquivos .txt que contêm códigos de mapa), todos na mesma pasta que o executável. Quando olho para a pasta, me dá vontade de chorar um pouco vendo tantos recursos, nunca vi um jogo que mostre todos os recursos diretamente; acredito que eles empacotam os recursos em um determinado arquivo.

Bem, é isso que estou tentando alcançar: espero compactar todas as imagens em um arquivo (talvez também os arquivos .txt) e poder ler esse arquivo ou adicioná-lo facilmente.

Bugster
fonte
Eu vi código em que todas as imagens foram agrupadas em uma sequência no código. Mas isso foi feito devido a requisitos. (Foi uma competição 64KB Java)
Omar Kooheji
Desculpe, foi uma competição java de 4Kb. Não é de 64Kb.
Omar Kooheji

Respostas:

62

Os programadores de jogos contam com um dos dois métodos principais de armazenamento de dados:

  • armazene cada arquivo de dados como um arquivo separado
  • armazenar cada arquivo de dados em um formato de arquivo personalizado

A desvantagem da primeira solução é o problema de espaço em disco desperdiçado, bem como o problema de instalações mais lentas.

A segunda solução fornece suas próprias armadilhas, primeiro é que você deve escrever toda a sua própria imagem / som / etc. rotinas de carregamento que usam uma API personalizada para acessar os dados arquivados. Uma desvantagem adicional é que você precisa escrever seu próprio utilitário de arquivamento para criar os arquivos em primeiro lugar.

A menos que você sempre carregue todos os arquivos do arquivo morto, o TAR / GZ pode não ser uma boa idéia, porque você não pode extrair arquivos específicos conforme necessário. Essa é a razão pela qual muitos jogos usam arquivos ZIP, que permitem extrair arquivos individuais conforme necessário (um bom exemplo é o Quake 3, cujos arquivos PK3 nada mais são do que arquivos ZIP com uma extensão diferente).

EDIT: "Ocultar" a estrutura de pastas do jogo e "Manter" apenas os executáveis

Outra solução é frequentemente usada para "ocultar" os arquivos do jogo na estrutura de pastas. Mantenha apenas os executáveis ​​e talvez um arquivo leia-me no diretório principal e mova os arquivos do jogo para uma subpasta chamada "data" ou outros relacionados.

EDIT: Gamedev Tuts Plus tem um bom recurso

EDIT: libarchive

Uma solução potencial libarchive, que é uma biblioteca de arquivamento que manipula a extração de arquivos de um archive, como um arquivo ZIP. Ele ainda permite atribuir o arquivo extraído a um ponteiro FILE padrão, o que tornaria a interface com outras bibliotecas potencialmente mais direta.

EDIT: arquivos em formato ZIP com extensão alternativa

Aqui, eu gosto do comentário de @Joachim Sauer

O uso de arquivos no formato ZIP com extensões alternativas também tem uma grande tradição fora dos jogos: Java faz isso , o OpenDocument Format (também conhecido como formato OpenOffice / LibreOffice) faz isso , até o Office Open XML (também conhecido como o "novo" formato do Microsoft Office) faz isso .

Mahbubur R Aaman
fonte
2
Sim, o Thief / SystemShock2 usou arquivos .zip renomeados também. Em Java, você pode usar algo como TrueZip para acessar arquivos em zips como se fossem arquivos em pastas, imagino que existam bibliotecas semelhantes para C ++.
Nick
18
O uso de arquivos no formato ZIP com extensões alternativas também tem uma grande tradição fora dos jogos: Java faz isso , o OpenDocument Format (também conhecido como formato OpenOffice / LibreOffice) faz isso , até o Office Open XML (também conhecido como o "novo" formato do Microsoft Office) faz isso ...
Joachim Sauer
5
@Svish. Dependendo da plataforma, a quantidade de espaço em disco ocupada por muitos arquivos pequenos pode ser consideravelmente maior que a quantidade ocupada por um arquivo grande, mesmo que esse arquivo grande não seja compactado ( .tarpor exemplo). Tem a ver com a maneira como os dados são fisicamente armazenados no disco.
TRiG 25/09/12
11
Ah, é verdade. Não deve ser muito, a menos que haja muito , mas nesse caso, pode realmente aumentar. Eu posso imaginar a instalação e desinstalação também é afetada por muitos arquivos pequenos.
Svish
2
Ligeiramente relacionado ao comentário de Kylotan, aqui está um post de Jonathan Blow no blog de desenvolvimento do The Witness sobre o uso de arquivos e como eles interagem com o mecanismo de correção do Steam. "O Witness empacota a maioria dos seus dados em um único arquivo de 2 gigabytes armazenado no formato .zip. Antes de carregar a versão inicial no Steam, tomei uma salvaguarda para minimizar o tamanho dos patches, ou pelo menos pensei [...] (Imagine esses arquivos são armazenados em ordem aleatória: provavelmente todo patch envolve todos os jogadores que baixam novamente o jogo inteiro!) "
Eric
39

Outra solução frequentemente usada para "ocultar" os arquivos do jogo é a estrutura de pastas. Mantenha apenas seus executáveis ​​e talvez um leia-me no diretório principal e mova os arquivos do jogo para uma subpasta "data". Não acho que seja muito incomum fazê-lo. Conheço muitos jogos que armazenam seu conteúdo dessa maneira.

tom van green
fonte
8
+1 Se o espaço em disco ou a proteção não for um problema, essa é a correção mais fácil.
Laurent Couvidou
11
+1 porque o outro cara disse +1. Não pode estar errado, não é? (Brincadeira à parte, grande resposta.)
jcora
Esta, na minha opinião, é a escolha ideal. Se o sistema de arquivos não conseguir lidar com essa eficiência com eficiência, o sistema de arquivos está quebrado e você deve se apoiar no criador do sistema operacional para melhorá-lo.
Onívoro 25/09/12
3
@ Oniforme Nem sempre é verdade, por exemplo, ao ler de um disco óptico, mesmo com um sistema de arquivos perfeito, é comum empacotar arquivos em ordem de carregamento para evitar busca excessiva (a velocidade pode realmente ser bastante surpreendente). Mas essa é uma história totalmente diferente para discos rígidos, e eu costumo pensar que o OP é neste caso.
Laurent Couvidou
3
@ Mr.Beast Você perdeu o meu ponto. Estou falando de discos ópticos. Eu trabalhei em um estúdio em que era um trabalho em tempo integral de um único programador para garantir que os arquivos fossem compactados da maneira mais eficiente possível em um DVD, para obter o melhor tempo de carregamento possível. Tenho certeza que ele ficaria feliz em saber que ele poderia apenas têm contado com o sistema de arquivos DVD;)
Laurent Couvidou
22

Eu realmente gosto do PhysFS por isso. Permite acessar pastas ou arquivos zip com o mesmo código. Funciona bem em todas as etapas da vida dos jogos.

  1. Durante o desenvolvimento : acesse os recursos diretamente de uma hierarquia de pastas. Dessa forma, os arquivos compactados não estão atrapalhando e você pode iterar rapidamente.
  2. Implantação inicial : junte seus recursos para facilitar a implantação / instalações rápidas. Nenhum código precisa mudar. Apenas aponte o PhysFS no zip em vez da pasta.
  3. Atualizações / Modding : O PhysFS pode carregar vários arquivos zip, onde os recursos de um substituem o outro. As atualizações podem ser tão simples quanto um novo zip, apenas com os arquivos alterados. Da mesma forma para modding.

atualizar:

Usei o tutorial incluído com a fonte e a documentação doxygen para aprender o PhysFS. A API é realmente bastante simples, você gastará mais tempo aprendendo a carregar imagens no SFML por meio de buffers de memória em vez de pelo caminho do arquivo.

deft_code
fonte
4
Estou usando o PhysFS no meu projeto atual e adoro isso. Nem sempre preciso regenerar meu arquivo de conteúdo; Eu posso simplesmente soltar uma versão atualizada no caminho de pesquisa e no BAM! Funciona.
Zack The Human
Após algumas respostas, decidi que irei com o physFS. Gostaria de recomendar um bom tutorial? :)
Bugster
12

Eu sugiro usar um arquivo ZIP. É um formato onipresente e você encontrará bibliotecas prontas que permitem carregar arquivos de dentro de um arquivo ZIP. Uma rápida pesquisa no Google revelou até um zip loader para sfml .

bummzack
fonte
3

Bem, você pode trapacear como eles mencionaram :) Você pode fazer uma folha de sprite a partir das imagens, não há necessidade de compactá-la hoje em dia, a menos que economize muito espaço. Depois de criar uma folha de sprite ou várias folhas de sprite a partir das imagens, você pode simplesmente renomear suas extensões. A maioria dos jogadores não se preocupa em verificar e por que não deixar essa opção para os artistas que desejam modificar seu jogo no futuro? Dessa forma, eles também podem criar uma folha de sprite, renomear sua extensão e começar a rolar.

Com os arquivos de texto, sugiro humildemente que você converta esses dados em formato binário. Tenho certeza de que você encontrará uma maneira simples de fazer isso. Por exemplo, se você usar apenas AZ, az e 0-9, poderá usar 6 bits para representar cada caractere, o que protegerá um pouco o seu material protegido por direitos autorais. também impedirá que outras pessoas editem mapas. Você sempre pode adicionar um conversor de mapas, se quiser. O zíper é completamente razoável para o texto.

wolfdawn
fonte
Converter em binário é um bom conselho, mas não para proteção - será mais fácil analisar e carregar mais rápido. O sugeriria como uma etapa de pré-processamento, mas isso não será o tópico da pergunta.
Maximus Minimus
Bem, suponho que, se ele quiser protegê-lo com mais eficácia, ele pode tentar criptografá-lo no RSA ou em um algoritmo semelhante (não há necessidade). Duvido que alguém faça uso não autorizado dos arquivos de mapa de um jogo independente, se estiver dentro de um arquivo binário. Simplesmente não parece valer a pena investir tempo em descobrir nossa análise. Os arquivos de texto são completamente vulneráveis ​​e, como você sugeriu algo ineficaz para armazenar dados.
wolfdawn
3
Nos HDDs, o carregamento de um único arquivo zip é mais rápido do que muitos arquivos pequenos, porque há buscas aleatórias menos caras no disco físico. Um binário para um jogo pequeno pode ser mapeado na memória e funcionar "magicamente", quase sem necessidade de análise.
Liosan 25/09/12
@Liosan Você poderia ter interpretado mal o que eu quis dizer ou o entendi errado. Eu disse que o binário é melhor para armazenar dados e que é improvável que outros designers de jogos desejem aprender a analisar seu código de mapa binário, a menos que seja documentado e incentivado a modificar propósitos. Portanto, oferece alguma proteção rudimentar sobre arquivos de texto.
wolfdawn
2

Não se trata apenas do número de recursos ou espaço em disco.
Com vários arquivos de textura diferentes, enquanto você usa o SFML, que é renderizado com o OpenGL, toda vez que você renderiza uma textura, o OpenGL precisa vincular a próxima textura à placa de vídeo (verifique glBindTexture ()) e é uma tarefa muito cara.
Com isso em mente, você pode entender por que os jogos geralmente colocam vários sprites na mesma textura, as chamadas planilhas, de acordo com seus menus / níveis / mapas do jogo.
O resultado é um enorme ganho de desempenho, pois você está processando muitos sprites com a mesma chamada de textura de ligação.

Edmo Freitas
fonte
Depois de obter várias referências para fazer uma planilha, considerei uma refatoração para diminuir a contagem de imagens. Obrigado
Bugster
2

Eu pessoalmente diria a rota do arquivo binário personalizado para isso. Isso é algo que eu faço o tempo todo agora, não é tão difícil quanto pode parecer e também fornece um nível de ofuscação para os arquivos de recursos do jogo. Escrevi um pequeno artigo introdutório sobre Gamedev sobre isso há pouco tempo, se você estiver interessado:

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

As folhas de sprite são um assunto completamente diferente, mas são a norma para a maioria dos jogos :)

Si Robertson
fonte
1

Outro método que você pode usar:

A versão gratuita do XnView fornece um recurso chamado " Strip of Images" (SHIFT + A), que permite criar sprite-collections.

Isso minimiza o acesso a arquivos e é particularmente importante para aplicativos / jogos da web para minimizar o número de HTTP-roundtrips.

O acesso a imagens individuais é concedido através de mapas de coordenadas (por exemplo, css-definition).

Lorenz Lo Sauer
fonte
0

Primeiro você deve escrever sua própria imagem / som / etc. rotinas de carregamento que usam uma API personalizada para acessar os dados arquivados. Uma desvantagem adicional é que você precisa escrever seu próprio utilitário de arquivamento para criar os arquivos em primeiro lugar. A menos que você sempre carregue todos os arquivos do arquivo morto, o TAR / GZ pode não ser uma boa idéia, porque você não pode extrair arquivos específicos conforme necessário. Essa é a razão pela qual muitos jogos usam arquivos ZIP, que permitem extrair arquivos individuais conforme necessário (um bom exemplo é o Quake 3, cujos arquivos PK3 nada mais são do que arquivos ZIP com uma extensão diferente). http://zpp-library.sourceforge.net/


fonte