Animação em Flash no Unity3D do zero. Parte um, lírica

Nesta série de artigos, falarei sobre como e por que decidimos criar nossa própria solução para importação de animação em Flash para o Unity, e sobre técnicas de otimização e funcionamento interno do plug-in. Também tenho muitas outras coisas fascinantes para contar: elementos internos do formato SWF, recursos especiais da extensão do editor do Unity e assuntos gerais de animação. Você encontrará tudo isso por dentro!




1. Introdução


Quando você começa a trabalhar em qualquer projeto, sempre precisa enfrentar o problema de escolher as tecnologias para a maioria de seus componentes. Um desses componentes é, obviamente, o sistema de animação. Agora, existem algumas variáveis ​​das quais sua escolha dependerá. A primeira pergunta que você deve se perguntar é com que ferramentas seus animadores estão acostumados (podem trabalhar) e quais são mais fáceis de encontrar. Certamente, escolher um produto extremamente específico não faz muito sentido. Nesse caso, se seus funcionários forem embora por algum motivo (ou forem atropelados por um ônibus), será quase impossível substituí-los. Portanto, basicamente, seu projeto, no todo ou em parte, será interrompido por um período indeterminado, o que pode ser muito caro, especialmente para um produto comercial. A segunda variável é mais técnica e está integrando as ferramentas ao seu mecanismo. Existem soluções de terceiros e qual é a qualidade delas? Você tem oportunidade e capacidade de criar sua própria solução? Obviamente, a eficiência e conveniência de todas as opções acima também são cruciais. E a terceira variável é a capacidade das ferramentas. Portanto, se você realmente precisa de cinemática inversa , seria muito estranho da sua parte preferir animação não esquelética.


Tipos de animação 2D


Agora, vejamos as técnicas de animação mais populares nos jogos. Considerarei apenas a animação em 2D, pois a animação em 3D é um tópico para uma conversa completamente diferente, com abordagens e ferramentas próprias. Sinta-se à vontade para pular esta seção se você for bem versado nesse assunto (confie em mim, não haverá revelações ou reveladores). Da mesma forma, se você estiver aqui apenas para ver os recursos da animação em Flash, você os encontrará no artigo abaixo.


Animação quadro a quadro


Iniciando nossa mini-revisão, o tipo de animação mais simples e mais antigo: animação quadro a quadro. Nesta animação, cada quadro é representado por uma imagem individual e, mudando essas imagens muito rapidamente, temos a ilusão de movimento.


Prós:


Implementação elementar, geralmente disponível para qualquer mecanismo. Qualquer complexidade e estilo de animação, você pode até inserir todos os quadros do filme (em teoria, é claro). Qualquer ferramenta: quase tudo pode fornecer uma sequência de quadros que você pode, se necessário, montar em um atlas de textura.


Contras:


A principal desvantagem é, obviamente, a quantidade de memória que tudo isso requer. Certamente, você pode usar todos os tipos de truques, como cortar quadros em blocos e, em seguida, reutilizar os blocos repetitivos, carregar em segundo plano os quadros do disco e remover os já mostrados, e assim por diante. Mas lembre-se de que todos esses truques também têm suas próprias desvantagens. Por exemplo, cortar blocos pode ser usado apenas em pixel art , o carregamento em segundo plano coloca uma pressão adicional no disco, ocupa muito espaço nesse disco, aumentando assim o tamanho do jogo em si, assim como a quantidade de dados necessários para um usuário iniciá-lo ou atualizá-lo.


Bottom line:


Funciona apenas para pequenos e poucos quadros de animação, perfeitos para pixel art e jogos de estilo retrô, como o NES .


Animação de vídeo


Basicamente, a animação em vídeo é uma apoteose da loucura quadro a quadro. E sim, ainda é aplicado e, às vezes, até com razão. Implementamos algo parecido com isso nos jogos Hidden Object para animações volumosas e complexas e também para cenas com uma pitada de realismo. Adicione a esses codecs como theora ou vp8 , e você poderá criar uma animação em vídeo bastante agradável (mesmo com composição alfa ).


O que é bom nesse tipo de animação é que você pode criar quase tudo, desde cenas gerenciadas pelo palco com atores reais até batalhas em 3D renderizadas. O ruim é uma grande carga na CPU quando você está decodificando e, é claro, a qualidade da imagem. O compromisso entre qualidade e eficiência pode ser alcançado apenas em um número limitado de casos específicos, como nos jogos de objetos ocultos mencionados acima.

De qualquer forma, a animação em vídeo não é para todos e nem sempre é aplicável, quase nunca, para ser precisa. Basicamente, esse tipo de animação funciona muito bem apenas nas cenas renderizadas. Se você conseguir fazer uma boa implementação dessa animação, com certeza não será fácil. Há muitas nuances e truques a serem lembrados, tanto em relação à qualidade da imagem de saída quanto à carga da CPU. Devido a essa especificidade, existem muito poucas implementações prontas para uso, que não são boas o suficiente ou custam muito dinheiro (olá, Bink_Video ), então a maioria das pessoas prefere escrever suas próprias.


Animação esquelética


Então, vamos avançar para os tipos mais populares e modernos de animação em 2D. As animações esqueléticas estão conquistando cada vez mais corações e mentes dos desenvolvedores de 2D, aproximando-se de ser o padrão de animação de jogos. O engraçado é que eles se tornaram tão populares em 2D relativamente recentemente, ao contrário do 3D, onde eles remontam quando nossos ancestrais estavam criando Half-Life . A essência da animação esquelética, você ficaria surpreso, é um esqueleto criado por um animador. Basicamente, um esqueleto é um conjunto de ossos conectados entre si e formando uma estrutura de árvore. Os ossos são unidos em pedaços, representados por figuras individuais. Essa construção começa a se mover quando os ossos são deslocados ou girados um em relação ao outro. As mudanças e rotações dos ossos do esqueleto seguem a linha do tempo geral da animação.


Os profissionais são óbvios: não precisamos armazenar todos os quadros de animação como uma imagem separada, apenas as peças (por exemplo, pernas e braços do personagem), que serão movidas pelos ossos. Existem algumas implementações realmente interessantes desse tipo de animação com tempos de execução para diferentes plataformas e mecanismos, que são acessíveis ou até gratuitos: Spine , Spriter , Anima2D , DragonBones e outros. Usando o esqueleto e seus recursos, você pode obter um nível incrível de suavidade da sua animação interpolando as posições dos ossos. Você também pode alternar as transições entre as cenas e até misturar dois tipos diferentes de cenas: fotografar enquanto corre, fotografar enquanto rasteja e assim por diante. Não vou listar todas as possibilidades de animação esquelética, então lembre-se de que existem muitas delas e elas são muito legais. E prefiro fornecer um link para o site da Spine, onde você pode dar uma boa olhada em todos eles, com fotos e descrições


Parece que conseguimos nosso soldado universal, mas não ainda. Ele também tem suas próprias desvantagens. E devo dizer imediatamente que, para muitos projetos e animações, essas desvantagens talvez nem existam. Portanto, se a animação esquelética funcionar para você - isso é ótimo, use-a, porque ela parece realmente fina e moderna.


Agora, voltemos aos inconvenientes. A animação esquelética requer uma montagem adicional. É sobre a criação de um esqueleto e vincular ossos e peças. Se o seu objeto tiver apenas uma animação, não poucas, como, por exemplo, o personagem do jogo de plataforma , esta etapa não será útil para você. Você também deve se lembrar que nem todas as cenas podem ser facilmente animadas com ossos. De fato, existem muitos exemplos em que é melhor sem eles, tanto em termos de criação quanto de desempenho final do jogo. Eu também apontaria a disponibilidade de especialistas no mercado como um fator importante. É claro que, com a crescente popularidade da animação esquelética, seu número também está aumentando, mas ainda assim provavelmente não será fácil para você colocá-las em sua equipe. A variedade de ferramentas também está fazendo sua parte. Todo mundo tem suas próprias preferências, e ainda é preciso ser flexível e pronto para aprender, o que cria dificuldades adicionais no recrutamento e treinamento de seus funcionários.


Animação da linha do tempo


Guardei esse tipo de animação por último, não porque seja melhor que todos os outros, mas porque é representado principalmente pela animação em Flash, cujo interior falaremos na parte técnica deste artigo. Agora, o Flash não é o único representante desse tipo de animação, mas certamente é o principal; portanto, a partir deste momento, vou descrever tudo em relação a ele. As cenas de animação da linha do tempo consistem em peças animadas em diferentes camadas na linha do tempo. Basicamente, é quase a mesma coisa que vimos na animação esquelética, mas sem esqueletos. Usando os quadros-chave na linha do tempo, podemos mover, girar, substituir e adicionar novas peças nesses quadros e, é claro, interpolar transições, ampliações e rotações entre eles. Isso significa que, nesse caso, movemos não os ossos aos quais as peças se ligam, mas as próprias peças. Claro, isso nos priva de muitas possibilidades de animação esquelética, mas, como eu disse antes, nem todo mundo precisa delas. Além disso, temos outras vantagens, como:


  • capacidade de adicionar e inserir novas peças no meio de uma cena;
  • sem cordame, sem ossos que às vezes são apenas desnecessários;
  • Adobe Flash (atualmente Adobe Animate ), o mais antigo e testado ao longo dos anos, ferramenta de animação; um grande número de animadores, de um jeito ou de outro, pode trabalhar com ele;
  • capacidade de usar cenas antigas ao transferir seus projetos do Flash para o Unity, incluindo as cenas feitas em gráficos vetoriais , não apenas em raster .

Você pode perguntar: o Flash não está morto? Como jogador de navegador - sim, mas como ferramenta de animação, ele ainda está no jogo. E vou lhe dizer mais, não há alternativas para o Flash agora ou previstas. Existem desvantagens? Claro. E a principal desvantagem é que ... não é animação esquelética, ha-ha. Portanto, estamos perdendo a capacidade de misturar nossas cenas, cinemática inversa e alguns outros recursos que você pode usar apenas quando trabalha com esqueletos. Mas temos linhas de tempo uma dentro da outra e também máscaras de varredura e vetor! E os animadores adoram máscaras! Aqui, é preciso observar que o Spine também adicionou recentemente a opção de recorte , mas até agora são apenas geométricos e severamente limitados em comparação com as máscaras do Flash.


Tipos de animação: Resumo


Obviamente, listei não todos os tipos de animação, mas apenas os principais. Por exemplo, deixei para trás a chamada animação processual, quando objetos ou peças são direcionados apenas por código, mas dificilmente é possível comparar esse com outros, e não queria que o artigo fosse muito longo para ser lido. Acho que agora é melhor olharmos mais de perto algo mais especializado em animação para completar a imagem.

Então, para resumir. Como sempre e em outros lugares, não há soldado universal aqui. Você precisa escolher sua solução, dependendo do seu projeto, tarefas e pessoas. Afinal, quem disse que você só precisa usar um tipo de animação por vez? Existem muitos projetos em que podemos ver todos os tipos de animação usados ​​e todos estão felizes. Animação em vídeo para cenas, esqueleto para personagens, linha do tempo para cenário, procedimento para vôo de sistemas de partículas de emissores e quadro único para as próprias partículas. Simplesmente tiramos o melhor de cada tipo.


Dilema e decisão de escrever nossa própria solução


De qualquer forma, por algumas razões objetivas, decidimos que para o nosso projeto precisamos de animação em Flash. Então surgiu a pergunta sobre a integração deles no mecanismo. Depois de experimentar várias opções de plug-in, optamos pelo que consideramos melhor por suas capacidades. Embora fosse vivo e bem suportado, também possuía uma licença empresarial completamente inacessível, mas quem realmente pode fixar o preço de um bom produto? Agora, intencionalmente, não vou lhe dar nomes, para não parecer propaganda ou antipublicidade.

Passamos quase um ano de desenvolvimento com este plug-in, período em que ficou claro por que não podemos continuar a usá-lo. Em particular, foi a qualidade de sua integração ao Unity. Isso resultou em bugs bastante sérios que não facilmente, não rapidamente e sem luta foram derrotados pelos desenvolvedores. O desempenho nos dispositivos de destino também foi terrível, e para nós ainda significa o nível do iPad 2 . Isso aconteceu porque tentamos fazer uma integração com um mecanismo específico, ignorando suas especificidades e buracos. Estávamos mais do que satisfeitos com a funcionalidade, mas os desenvolvedores se recusaram a abrir o código-fonte para nós, mesmo individualmente. Então, foi assim que decidimos escrever nossa própria solução.

Tive uma experiência bastante bem-sucedida ao escrever extensões para o Unity e um pouco de experiência na conversão de cenas de animação em Flash para meus próprios formatos. Já faz algum tempo desde o último, para ser justo, mas algo que ainda me lembrava. Ao mesmo tempo, tomei a decisão de escrever tudo isso como um projeto de estimação, para não depender do projeto principal ou da empresa em que trabalho. E, convenhamos, é bom ter essa produção por conta própria. De qualquer forma, armado com uma especificação de formato SWF de 250 páginas, eu entrei na batalha.


Opções de exportação


Para começar, vamos discutir as opções que temos para exportar animação do editor Flash. Existem alguns deles, cada um com suas próprias vantagens e desvantagens. Nós vamos revisar os principais.


Formato .XFL


No editor de animação Flash, você pode salvar o arquivo de origem em um formato .XFL não compactado, em vez do .FLA fechado definido por padrão. Agora, é fácil trabalhar com esse formato, mas não possui documentação. Basicamente, ele consiste em alguns subdiretórios e um monte de arquivos .XML que descrevem todos os estados dos clipes armazenados. O formato da descrição também é muito simples e compreensível, como você pode ver no exemplo abaixo:


static_clip.xml

<DOMSymbolItem name="static_clip" itemID="5c719f28-00000051" lastModified="1550950184"> <timeline> <DOMTimeline name="static_clip"> <layers> <DOMLayer name="Layer_1" color="#00FFFF" current="true" isSelected="true"> <frames> <DOMFrame index="0" keyMode="9728"> <elements> <DOMBitmapInstance selected="true" libraryItemName="bitmap.png"/> </elements> </DOMFrame> </frames> </DOMLayer> </layers> </DOMTimeline> </timeline> </DOMSymbolItem> 
Link de origem

O que obtivemos aqui é este clipe, static_clip com uma camada, Layer_1 e um quadro que armazena uma imagem raster chamada bitmap.png .


movie_clip.xml

 <DOMSymbolItem name="movie_clip" itemID="5c719f30-00000053" lastModified="1550950713"> <timeline> <DOMTimeline name="movie_clip"> <layers> <DOMLayer name="Layer_1" color="#00FFFF" current="true" isSelected="true"> <frames> <DOMFrame index="0" duration="4" tweenType="motion" motionTweenSnap="true" keyMode="22017"> <elements> <DOMSymbolInstance libraryItemName="static_clip"> <matrix> <Matrix tx="-50" ty="-50"/> </matrix> <transformationPoint> <Point x="28.5" y="27.5"/> </transformationPoint> </DOMSymbolInstance> </elements> </DOMFrame> <DOMFrame index="4" tweenType="motion" motionTweenSnap="true" keyMode="22017"> <elements> <DOMSymbolInstance libraryItemName="static_clip" centerPoint3DX="128.5" centerPoint3DY="127.5"> <matrix> <Matrix tx="100" ty="100"/> </matrix> <transformationPoint> <Point x="28.5" y="27.5"/> </transformationPoint> </DOMSymbolInstance> </elements> </DOMFrame> </frames> </DOMLayer> </layers> </DOMTimeline> </timeline> </DOMSymbolItem> 
Link de origem

Aqui você pode ver a descrição do clipe movie_clip , que consiste em dois quadros-chave com os índices 0 e 4, respectivamente. Nesses quadros, nosso clipe static_clip é armazenado pelas coordenadas (-50;-50) e (100;100) . Aqui há interpolação de movimento entre os quadros (uma animação processual, no nosso caso, é apenas uma mudança, sem redimensionamento e rotação). Assim, a posição do clipe estático entre os quadros principais pode ser calculada usando a interpolação linear das coordenadas que extraímos desses quadros.

É claro que, no caso de uma animação real, tudo será um pouco mais complicado e volumoso, mas ainda assim tudo pode ser entendido, mesmo sem documentação. E pode parecer para você que é isso. E, na verdade, estou ciente de vários projetos e empresas que foram desta maneira e tiveram bastante sucesso, mas não sem algumas limitações e dificuldades. E essas dificuldades são a verdadeira colisão do .XFL, que são:


  1. As interpolações podem ser muito diferentes, tanto simples - com interpolação linear quanto mais complexas - com funções e gráficos personalizados dessa interpolação; os gráficos vetoriais que se transformam em interpolações são executados apenas de acordo com suas próprias regras, compreensíveis para as pessoas da Macromedia e da Adobe;
  2. Os gráficos vetoriais, assim como todas as animações, exceto os gráficos de varredura, são descritos em um arquivo de texto., Por exemplo . Isso significa que você precisa escrever seu próprio rasterizador, o que, devido à natureza e complexidade do formato vetorial no Flash, não pode ser feito;
  3. As regras para reprodução de animação, incluindo as aninhadas, precisam ser criadas do zero. Não existe documentação para isso, e respostas para perguntas como quando e qual quadro deve ser mostrado, quando interpolar e quando deixá-lo sem interpolação, você precisará descobrir por conta própria, ao mesmo tempo em que tenta abranja todos os casos possíveis durante as execuções de teste, o que, acredite, é um exercício não trivial para uma solução geral, não privada.

Essas não são todas as desvantagens dessa abordagem, mas acho que são suficientes para você entender que isso funcionaria para uma solução geral apenas com fortes limitações. Há muito tempo, segui esse caminho trabalhando em um dos meus projetos. Havia cenas do Flash com interpolações clássicas (sem regras de interpolação personalizadas e funções especiais de interpolação), gráficos de varredura apenas e outras oportunidades avançadas fornecidas pelo editor do Flash. Eu vim com essa solução proprietária com bastante rapidez e eficiência, mas ainda exigia algumas limitações severas aos animadores, para que eles não usassem nada que você possa chamar de complicado. A abordagem tem o direito de existir e existem algumas bibliotecas baseadas nela, com graus variados de shabbiness, mas, como eu disse, funciona com muitas limitações.


Scripts .JSFL


Outra opção quase funcional para obter informações sobre nossas animações, os scripts .JSFL permitem que você estenda seu editor Flash, interaja com seu ambiente, edite sua animação e, é claro, obtenha todas as informações necessárias sobre as linhas de tempo, camadas, clipes e quadros dentro . Também é usado pelos animadores para automatizar vários processos, mas essa é realmente uma história completamente diferente. Como um todo, a abordagem possui todas as desvantagens da anterior, então não vou me aprofundar nisso. Deixe-me apenas dizer que ele permite exportar suas cenas de animação, por exemplo, quadro a quadro, mas sabemos que não é isso que um Jedi real faria (mas, é claro, isso pode ser feito em alguns projetos). Voltaremos a esses scripts mais tarde, quando discutirmos a abordagem que escolhi: para rasterização de gráficos vetoriais e otimização das cenas exportadas.


Aplicativo AIR


Essa abordagem está realmente funcionando e pode ser usada como deveria. Ainda assim, não escolhi, mas vou falar sobre essa opção, só para constar. A essência dessa abordagem é que criamos um aplicativo AIR no próprio Flash ou, para puristas, por exemplo, no Haxe . Este aplicativo extrai todas as informações das cenas de animação que você já compilou no formato SWF. Na aplicação, reproduzimos a cena quadro a quadro, obtemos todas as informações sobre os quadros e as salvamos no formato mais adequado ao nosso tempo de execução. Usando esse método, abordamos todos os problemas mencionados acima:


  • não precisamos rasterizar nossos gráficos vetoriais, pois isso será feito pelo tempo de execução do Flash. A única coisa que resta a fazer é obter essas informações e salvar a saída raster de nossas partes vetoriais;
  • não precisamos inventar regras de reprodução e lidar com interpolação de interpolação personalizada, o Flash player integrado ao aplicativo AIR sabe exatamente como isso deve ser feito e basicamente faz o trabalho para nós;

Como bônus, temos a oportunidade de usar scripts de quadro (todo o play() , stop() e outros gotoAndPlay() , alguns animadores realmente gostam deles). Como desvantagem, perdemos a oportunidade de exportar as cenas em loop no próprio Flash. Mas não é tão ruim assim, pois podemos repeti-los em nosso tempo de execução, e os animadores podem preparar tudo para isso.


Note-se agora que tenho certeza de que tudo será mais ou menos difícil do que eu o descrevo, já que eu pessoalmente não fui lá, então não posso realmente contar todos os detalhes. Congratulo-me com aqueles que seguiram este caminho para compartilhar sua experiência. Ficarei feliz em ler sobre seus sucessos e fracassos!


Seu próprio flash player


Esta é provavelmente a opção mais justa, óbvia e direta entre todas, mas também é a mais difícil. Afinal, é isso que um Flash player real faz, aquele que a maioria de nós instalou no navegador favorito como complemento. Agora, os representantes populares desse gênero são: gameswf e, nascidos do primeiro, scaleform . Ambos estão mortos hoje. O que é fascinante sobre eles é que eles foram usados ​​principalmente para implementações de GUI em vários projetos, incluindo AAA . Mas nosso interesse é nas partes internas, não nas aplicações de bibliotecas mortas.


Qualquer Flash player decente possui pelo menos duas coisas importantes ocultas:


  • Analisador de formato SWF;
  • rasterizador de gráficos vetoriais;
  • máquina virtual para iniciar o ActionScript do código;
  • biblioteca padrão para um código personalizado;

Eu sei que você pensa. Cada um desses pontos acima grita que, mesmo que algo como isso seja possível de implementar, você precisará mudar mais de uma equipe para esta tarefa e passar alguns anos no desenvolvimento da versão básica. Mesmo a implementação de uma pequena parte apenas para reproduzir alguma coisa levará um longo tempo e você pode ter certeza de que as adições adicionais na forma de muitas partes não documentadas desse pipeline dobrarão esse longo período.


Sim, a Internet está cheia de tentativas de implementar cada uma dessas partes, variando em graus de shabiness e buggedness. Mas você não pode nem considerar esses desenvolvimentos como base para suas próprias coisas, pois você precisaria passar anos apenas para caçar bugs. Além disso, você teria que adicionar todos os testes de unidade não escritos antes de perceber que nunca será capaz de implementar totalmente todas as pequenas coisas. Aqueles caras que tentaram adicionar os recursos necessários ao gameswf entenderão do que estou falando. Um Flash player justo também deve rasterizar os gráficos vetoriais sem antecedência, mas no tempo de execução, o que causará um impacto tão grande no desempenho que nem todo projeto pode passar. A propósito, quero dizer olá aos sobreviventes que tentaram usar o scaleform em dispositivos móveis. De qualquer forma, esta é a maneira mais solene e sem esperança, e definitivamente não é a nossa escolha.


Combinando as abordagens


Então, finalmente vamos à minha opção. Tendo estudado todas as formas possíveis, criei essa combinação interessante. É relativamente fácil de implementar, gerenciável por uma pessoa e, ao mesmo tempo, possui funcionalidade suficiente para atender a todas as necessidades de praticamente qualquer produção de animação em linha do tempo 2D.


Primeiro, vamos usar a cena de animação compilada no SWF, para não inventar várias opções de reprodução e quase nunca adivinhar como o Flash player funciona por dentro, pois não podemos cobrir todos os casos, mas ainda estamos procurando a solução geral. Além disso, o editor Flash se livra de todas as interpolações que usamos em nossa animação, fornecendo apenas as posições vazias das peças no SWF compilado.


Segundo, proibimos o uso de scripts em animação. Sim, esse requisito é certamente muito difícil e triste, mas não tenho uma equipe inteira de programadores para implementar uma máquina virtual decente e uma biblioteca padrão que eles teriam que escrever quase de olhos vendados. Aqui, é claro, você pode ver uma desvantagem da minha abordagem em comparação com o método de aplicativo do AIR. No segundo, poderíamos usar alguns scripts para reprodução interna de animação. Ao mesmo tempo, isso não nos impede de criar boas cenas de animação. Para transferir informações personalizadas da cena para o jogo, você pode usar os chamados frame labels , que você encontrará no código. Além disso, você pode fixar eventos do usuário nos quadros específicos usando as funções de retorno de chamada do tempo de execução.


Em seguida, nos livramos de escrever nosso próprio rasterizador de gráficos vetoriais, pois não podemos escrevê-lo para o caso geral e para cobrir todas as opções e possibilidades de vetor no Flash. Em vez disso, rasterizaremos nossos gráficos antes da compilação (!) Usando um script JSFL. Enquanto isso, usando esse mesmo script, otimizaremos nossos gráficos vetoriais mesclando clipes estáticos em uma imagem e ampliar ou reduzir as imagens rasterizadas resultantes em prol de nossa própria prioridade: qualidade e / ou desempenho. Também aqui vale a pena considerar as opções de qualidade / resolução da arte para dispositivos com várias densidades de pixel da tela (por exemplo, arte em HD e SD).


Conclusão da parte lírica


Isso conclui a primeira parte do meu artigo. No segundo, discutiremos detalhes técnicos da implementação, fragmentos de código, figuras (!), Otimização, truques e ajustes. Em breve, não perca!

Source: https://habr.com/ru/post/pt445102/


All Articles