Como compactar um mínimo de animação quadro a quadro no jogo no disco

19

Estou desenvolvendo um jogo como o Age of Empire (edifícios no mapa) e para cada prédio tenho uma planilha de sprites para sua animação. Estou usando a animação quadro a quadro para animar o edifício (sem conhecer nenhum outro método). Percebo que minha pasta de recursos está indo extremamente grande devido às imagens que estou colocando nela.

Como jogos como CoC e Age of Empires mantêm seu tamanho de apk abaixo de 50 Mg? Estou perdendo alguma coisa aqui quando se trata de desenvolvimento de jogos

Obrigado

EDIT: Mais informações sobre o problema que estou enfrentando

Eu tenho muitos objetos desenháveis ​​de animações. Eu escolhi esse caminho porque era o mais rápido e estava produzindo os resultados que eu queria. Basicamente, todo edifício é um desenho de animação no qual seu arquivo xml se refere a 8 desenhos (8 imagens = 8 arquivos). Todos eles são PNG devido à transparência. Como tenho mais de 200 imagens, o tamanho do apk é 120 MB (e ainda não terminei de copiar metade dos arquivos). É isso que pronto, tem que haver uma maneira de resolvê-lo. Por favor, ajude um colega desenvolvedor

Serpente
fonte
Compactar imagens ou separar o conteúdo do jogo do apk pode ser o que você está procurando.
János Turánszki
Você quer dizer arquivos de expansão? O problema de que os arquivos de expansão não têm pastas de densidade diferentes. É isso que os jogos fazem? Estou fazendo animação quadro a quadro (imagem completa do edifício). Ou estou totalmente no caminho errado
Snake
Por precaução, tentei ajudar e colocar uma resposta relacionada à economia de espaço para suas imagens. No entanto, sua pergunta é confusa: não está claro se você deseja realmente conhecer técnicas como relacionadas a "como jogos como CoC e Age of Empires mantêm seu tamanho de apk abaixo de 50 mg?" ou se você quiser apenas verificar se há menos formas de animar o espaço em disco (como sugere o título). Esclareça, para que eu possa excluir minha resposta, se for esse o caso, e também para que você possa obter respostas mais precisas.
Mand
@MAnd Eu editei a minha resposta para refletir sobre o problema ainda mais
Cobra
2
Para o Age of Empires, é provavelmente uma combinação de baixa resolução (IIRC, projetada para 640x480) e imagens indexadas (não RGB total).
user253751

Respostas:

24

Não está claro por sua pergunta se você realmente deseja conhecer técnicas que permitem que os jogos economizem espaço em disco, mesmo com grandes quantidades de arquivos de imagem / recursos pesados ​​(é o que está no corpo da pergunta), ou se você só quer saber se há menos formas de fazer animação para os seus edifícios com menos espaço em disco (é isso que está implícito no título da sua pergunta).

Então, vou colocar essa resposta aqui, tentando ajudar em relação à economia de espaço quando você tiver muitas imagens. Se você estiver interessado apenas em conhecer técnicas de animação que possam permitir economizar espaço em disco, entre em contato para que eu possa excluir a resposta.


Dito isto, em uma situação semelhante, duas soluções que eu vi (e usei uma vez) em termos de economia de espaço no disco foram:

1) concatenar imagens individuais dentro de uma mesma imagem. Às vezes, pode ser útil. Portanto, em vez de salvar 4 arquivos separados para cada um dos quadrados coloridos a seguir, salvei todos lado a lado na mesma imagem (e os dividirei apenas pelo código do jogo):

insira a descrição da imagem aqui

Neste exemplo, salvar cada um em quatro arquivos PNG diferentes equivale a 1255 bytes, enquanto o arquivo único com todos os concatenados é 451 bytes. Obviamente, o quanto isso pode ajudar depende de cada caso e você deve testar para ver se isso pode ser útil para você, dependendo de suas imagens.

2) para compactar a pasta de recursos. Isso geralmente pode ser muito útil para economizar espaço em disco. Então, quando o jogo está em execução, você descompacta ou extrai a imagem desejada do arquivo compactado - dependendo do formato de compactação usado. Veja esta resposta anterior que se tornou um wiki deste site: /gamedev//a/37649/72423

Mas lembre-se de que cada tipo de compactação pode ser mais ou menos vantajoso, dependendo do tipo de arquivo de imagem usado : Evite a compactação dupla de recursos

Para mais detalhes sobre compactação: estado da arte em compactação de imagem?


Por fim, você também pode estar interessado em pensar quais tipos de imagem usar para cada situação: Qual formato de imagem é mais eficiente em memória: PNG, JPEG ou GIF?

MAnd
fonte
Obrigado pela informação. É estranho que você tenha conseguido reduzir o tamanho do arquivo pela metade, colocando as coisas em um arquivo. Eu pensei que, no final do dia, é a mesma contagem de pixels e espaço usado. Eu editei minha pergunta para uma melhor resposta
Snake
@Snake Então, pela edição que você fez, acho que minha resposta pode realmente ser útil. Concatenar imagens + compactar pode reduzir muito o tamanho da pasta. Ambas as técnicas são usadas regularmente em alguns tipos de jogos. Sobre a concatenação, esse é sempre um truque surpreendente. Tente você mesmo: coloque as imagens de uma sequência de uma animação sua lado a lado e compare o tamanho final com a soma das imagens individuais. Então você pode ver se isso ajuda no seu caso. Quanto à compressão, para PNGs ele tende a ser menos eficaz, mas ainda vale a pena o esforço para tamanho do corte da sua pasta final
Mand
@ Cobra uma observação, no entanto: concatenar às vezes não vale ou até aumenta um pouco o tamanho final. Mas, muitas vezes, pode proporcionar uma redução desejável. Tudo depende das suas imagens #
19/11/2015
Lembro-me de tentar as duas técnicas e a redução foi inferior a 10%. Eu definitivamente sei que a compactação não importa com PNG, mas tentarei a concatenação. É por isso que eu perguntei como outros jogos de fazê-lo porque, obviamente, eles têm maneira mais gráficos do que o meu
Cobra
Você não deve conseguir compactar uma pasta cheia de imagens. As imagens já devem estar compactadas e não devem ter muitas seqüências repetíveis. Se o fizessem, essa camada extra de compressão seria parte do codec de imagem ...
corsiKa
9

Eu proporia que você tente o TexturePacker

  • você pode simplesmente arrastar e soltar todas as suas imagens e empacotá-las
  • você pode aplicar compactação diferente - por exemplo, usar PNGs indexados que consomem muito menos memória - até 70% menos em comparação com um arquivo PNG padrão
  • você pode criar um arquivo de dados que contém o nome + a posição de cada um de seus edifícios
  • a versão gratuita já pode ser suficiente para criar as folhas de sprite para você

Você usa uma estrutura de desenvolvimento de jogos como AndEngine, Cocos2d-x ou LibGdx? => Nenhum

Você precisa de todas as suas imagens carregadas ao mesmo tempo? Parece que você terá grandes problemas de RAM nos dispositivos de destino.


Atualização: Snake me enviou algumas imagens. Como prometido, não os tornará públicos aqui, então eu mesmo criei algumas artes para demonstrar como reduzir o uso de memória.

Na imagem original, apenas uma parte da imagem estava em movimento. Coloquei um pássaro em uma casa para demonstrar isso:

insira a descrição da imagem aqui

Basicamente, empacotar a animação completa em uma folha é um grande desperdício de memória. Você deve dividir as partes estáticas e móveis:

Estático:

insira a descrição da imagem aqui

Anim01:

insira a descrição da imagem aqui

Anim02:

insira a descrição da imagem aqui

Mantenha a posição original do pássaro nas imagens . É por isso que há tanto espaço vazio acima. Você precisa disso para alinhar a animação.

Agora arraste as imagens no TexturePacker e selecione os seguintes parâmetros

  • Formato de dados: hash JSON (ou XML, se você preferir)
  • TrimMode: Trim (isso cria retângulos)
  • Formato de pixel: 8 bits INDEXADO - para criar PNGs de 8 bits (cerca de 70% menos memória)
  • Permitir rotação: false
  • Digite um nome de arquivo para os dados

TexturePacker embalando as imagens

O resultado é que agora você obtém 2 arquivos: a folha de sprite e um arquivo de descrição JSON.

"house_anim_01.png":
{
    "frame": {"x":351,"y":246,"w":110,"h":79},
    "rotated": false,
    "trimmed": true,
    "spriteSourceSize": {"x":67,"y":8,"w":110,"h":79},
    "sourceSize": {"w":400,"h":400},
    "pivot": {"x":0.5,"y":0.5}
},

As partes importantes são frame e spriteSourceSize .

O quadro fornece a localização do sprite original na folha de sprite.

spriteSourceSize fornece o deslocamento para desenhar a imagem - as partes da imagem que são deixadas de fora devido ao corte:

Uma rotina simples de desenho de pseudo-código se parece com isso:

drawImage(spritename, posX, posX)
{
    data    = sheetData[spritename]
    offsetX = data.spriteSourceSize.x
    offsetY = data.spriteSourceSize.y
    frameX  = data.frame.x
    frameY  = data.frame.y
    width   = data.frame.w
    height  = data.frame.h
    screen.draw(sheetImage, posX+offsetX, posY+offsetY, width, height)
}

Pode ser necessário ajustar o cálculo do deslocamento, dependendo do ponto / origem do pivô no seu sistema gráfico. A rotina acima pressupõe um sistema de coordenadas cuja origem é superior esquerda.

Em seguida, basta desenhar a casa em 2 passagens:

draw("background", 100, 100);
draw("anim_01", 100, 100);

Você não precisa se preocupar com as compensações - já que as imagens já estão alinhadas.

Andreas Löw
fonte
+1 para a observação sobre o uso de RAM, o que outras pessoas estão ignorando
Dan Hulme
@ Andreas Vou verificar isso. Obrigado. Não ria de mim, mas não estou usando um motor. É feito principalmente com animação e drawables e funciona como um encanto. Não carrego todas as imagens na memória; caso contrário, ele travará. Apenas carrega as imagens necessárias para exibição no momento. Você acha que a sugestão acima funcionaria com o SDK padrão do Android?
Snake
1
Sim vai. O TexturePacker possui 2 modos para aparar sprites: retângulos e polígonos. Se você usar imagens isométricas, poderá obter uma grande vantagem das malhas poligonais em termos de embalagem. A questão é se você seria capaz de desenhar triângulos texturizados - ou retângulos com uma máscara. Se não for esse o caso, você ainda poderá usar os retângulos. Você pode me enviar algumas de suas imagens se quiser usar o dropbox e enviar um link para -> support em codeandweb. com. Não vou compartilhá-los - apenas interessados ​​em ver o que podemos fazer para melhorar a embalagem.
Andreas Löw
@ AndreasLöw Sinto muito, não recebi uma notificação do seu comentário. Acabei de ver. Eu aprecio muito a ajuda. Vou lhe enviar uma coisa e talvez você possa esclarecer o que devo. ... meio que fico preso a algo em que tenho pouca experiência e talvez você possa lançar luz. I entrará em contato com você em breve
Cobra
7

Aqui estão alguns ponteiros que você pode usar

  1. Tente garantir que todas as imagens em segundo plano e não transparentes não estejam no formato PNG
  2. Tente ter todas as animações ativadas por loop, ou seja, se a animação for 1,2,3,4,5,6, tente torná-la como 1,2,3,4,3,2,1, onde esses números são o número de quadros da animação, isso ajuda muito
  3. se muitas imagens são iguais e apenas a cor difere (geralmente botões da interface do usuário, m animações de partículas, moedas de jogo), tente capturar uma imagem em branco e alterar sua cor dinamicamente
  4. Tente criar seu .apk apenas com imagens extremamente importantes e carregue tudo de um servidor e mantenha a memória do telefone

Espero que esses indicadores ajudem

PS: Eu só dou uma idéia generalizada, pois não conheço o conteúdo exato do jogo e peço desculpas se esses indicadores não forem úteis

Kumar Saurabh
fonte
Você também pode: 1) comprimir todas suas imagens 2) telhas de uso o mais rápido possível 3) imagens concatenar togetter em uma imagem maior e usar isso como o mapa uv para texturização
Anthony Raimondo
Essas são ótimas sugestões. Obrigado. Acho que o ponto mais importante é 4. No entanto, se for esse o caso, como colocá-los nas diferentes pastas desenháveis ​​e referenciá-los como R.drawable.image1? É onde eu estou confuso
Cobra
4

Muitos jogos não mantêm seus recursos gráficos no .apk; eles incluem apenas o "básico", como gráficos da interface do usuário e o código do jogo e baixam o restante dos recursos depois que o jogo é instalado. Isso é especialmente verdadeiro para jogos que usam recursos gráficos diferentes, dependendo da resolução da tela, para impedir que o .apk tenha que conter ativos de baixa resolução e alta resolução.

Você deve considerar as opções de otimização fornecidas pelos outros respondentes, bem como, finalmente, você terá que veicular os gráficos do seu jogo separadamente do próprio .apk.

Sandalfoot
fonte
Não tenho problemas em obter os gráficos do servidor (ou até de arquivos de expansão), mas como os coloco na pasta drawable para que eu possa referenciá-los por R.drawable.x Como a maioria dos meus (muitos) xmls os referencia usando R .drawable
Snake
AFAIK, você não pode. Uma solução alternativa é manter uma tabela de hash de nomes de arquivos de recurso vinculada a IDs de recurso e usar o AssetManager para capturar os arquivos com base nessas IDs, mas talvez seja necessário refazer os arquivos .xml se você seguir esse caminho.
Sandalfoot
4

Eu vim a este site procurando uma pergunta semelhante e existem alguns bons recursos apontados nas respostas à sua pergunta e em outras perguntas.

Você provavelmente deveria dar uma olhada na animação 2D: modelos 3D animados ou sprites com quadros de animação? para algum debate sobre diferentes tipos de animação. Isso me ajudou a otimizar meu jogo. Além disso, você não nos diz qual API você está usando ou qual mecanismo você usa. Só isso já pode fazer muita diferença: animação PNG quadro a quadro do Android

Além disso, lembre-se de que, se você seguir a rota de compactação, poderá haver diferenças importantes entre a forma como você compacta. Especificamente, existem algumas diferenças entre os tipos de compactação e há um debate especializado sobre qual é a rota mais apropriada para dispositivos móveis. Especialmente se você levar em conta que, para dispositivos móveis, o uso de RAM e o desperdício de CPU para carregamento também são fundamentais. Consulte: http://www.gamasutra.com/blogs/AlexandruVoica/20130419/190833/Why_efficiency_is_key_in_texture_compression_standards_for_mobile_graphics.php?print=1

Bennton
fonte
Obrigado Bennton, sou realmente novo no desenvolvimento de jogos. Desenvolvi vários aplicativos baseados em ferramentas / produtividade. Mas nenhum com jogos. Então, estou fazendo meu primeiro jogo e não estou usando um mecanismo. Estou usando apenas AnimationDrawables e as coisas estão funcionando muito bem. É apenas o tamanho do apk está ficando fora de mão
Cobra
Bennton, o último link sugerido por você é particularmente interessante. Muito obrigado por compartilhar isso! Verifique a última da minha resposta, que também aborda a questão da compactação diferente para diferentes tipos de arquivo. Na verdade, parece haver tipos de compactação que funcionam melhor com tipos de imagem já compactados como PNG ou melhor com tipos de imagem não compactados. Experimentar para cada caso é sempre a melhor maneira de verificar o que funciona melhor para cada situação.
Mand