O motor Cocos tem principalmente três tipos de cache, que são cache de textura, cache de frame sprite e cache de animação. qual é:
> Cache de textura: TextureCache
> Cache de Frame Sprite: SpriteFrameCache
> Cache de animação: AnimationCache
O objetivo do cache é carregar os recursos necessários (como imagens de textura) na memória primeiro e, em seguida, quando os recursos forem usados novamente, eles podem ser retirados diretamente da memória sem recarregar. Reduzindo assim o uso de memória de CPU e GPU.
Este artigo classifica e integra o conteúdo das referências e adiciona algumas de suas próprias opiniões.
【TextureCache】
1. Visão Geral
Muitas imagens de textura precisam ser carregadas no jogo, e essas operações consomem muita memória e muitos recursos.
Quando há uma interface no jogo que usa muitas imagens, a velocidade é muito lenta quando a interface é clicada pela primeira vez (porque há muitas imagens a serem carregadas e desenhadas), podemos usar TextureCache para carregar de forma assíncrona a textura com antecedência, e quando o carregamento terminar, digite Será muito rápido usar essas imagens nesta interface.
> Texture2D (textura): o objeto de textura para operação de CPU e GPU após a imagem ser carregada na memória.
> TextureCache (cache de textura): usado para carregar e gerenciar texturas. Depois que a textura é carregada, ela pode ser usada na próxima vez para retornar à textura carregada anteriormente, reduzindo assim o uso de memória da GPU e CPU.
Quando você cria um sprite, normalmente usa Sprite :: create (fileName). Se você observar a implementação de Sprite :: create (fileName), verá que ele adiciona esta imagem ao cache de textura.
//
Sprite * Sprite :: criar (const std :: string & nome do arquivo)
{
Sprite * sprite = novo Sprite ();
if (sprite && sprite-> initWithFile (nome do arquivo))
{
sprite-> autorelease ();
sprite de retorno;
}
_SAFE_DELETE (sprite);
return nullptr;
}
bool Sprite :: initWithFile (const std :: string & nome do arquivo)
{
ASSERT (filename.size ()> 0, "Nome de arquivo inválido para sprite");
// Carrega a imagem da textura do nome do arquivo
Texture2D * texture = Director :: getInstance () -> getTextureCache () -> addImage (nome do arquivo);
if (textura)
{
Rect rect = Rect :: ZERO;
rect.size = textura-> getContentSize ();
return initWithTexture (textura, rect);
}
retorna falso;
}
//
2. Obtenha TextureCache
Na versão 3.x, TextureCache não é mais usado como um modo singleton. Em vez disso, é usado como uma variável de membro do Diretor e obtido da seguinte maneira.
//
// Obtenha a classe de cache de textura TextureCache
Diretor :: getInstance () -> getTextureCache ();
//
3. Carregando e obtendo textura
Se o nome do arquivo não tiver sido carregado antes, ele criará um novo objeto Texture2D e o retornará. Ele usará o nome do arquivo como a chave, caso contrário, ele retornará uma referência à imagem carregada anteriormente.
> addImage: A função retornará uma referência à textura Texture2D, que pode ser carregada recentemente na memória, ou pode já existir antes.
> getTextureForKey: obtém o cache de textura correspondente a esta chave.Se a textura correspondente a esta chave não existir, então nullptr é retornado.
> Os formatos de imagem suportados são: .png, .bmp, .tiff, .jpeg, .pvr.
//
// addImage carrega imagens de textura
// Suporta formatos de imagem: .png, .bmp, .tiff, .jpeg, .pvr
Texture2D * texture = Director :: getInstance () -> getTextureCache () -> addImage (nome do arquivo);
// getTextureForKey Obter imagem de textura
Texture2D * texture = Director :: getInstance () -> getTextureCache () -> getTextureForKey (textureKeyName);
//
4. Carregue a textura de forma assíncrona
A classe TextureCache também oferece suporte à função de recursos de carregamento assíncrono, usando o método addImageAsync. Você pode adicionar um método de retorno de chamada ao método addImageAsync, para que possa ser notificado quando o carregamento assíncrono da textura terminar.
> Os formatos de imagem suportados são: .png, .jpg.
Você pode escolher o modo de carregamento assíncrono para adicionar uma barra de progresso à cena de carregamento.
O código-chave é o seguinte:
//
TextureCacheTest :: TextureCacheTest ()
: _numberOfSprites (20)
, _numberOfLoadedSprites (0)
{
tamanho automático = Diretor :: getInstance () -> getWinSize ();
_labelLoading = Label :: createWithTTF ("carregando ...", "fonts / arial.ttf", 15);
_labelPercent = Label :: createWithTTF ("% 0", "fonts / arial.ttf", 15);
_labelLoading-> setPosition (Point (size.width / 2, size.height / 2 - 20));
_labelPercent-> setPosition (Point (size.width / 2, size.height / 2 + 20));
this-> addChild (_labelLoading);
this-> addChild (_labelPercent);
// Carregar imagem de textura de forma assíncrona addImageAsync
// Depois de carregar a textura, a função de retorno de chamada será executada
Director :: getInstance () -> getTextureCache () -> addImageAsync ("Images / HelloWorld.png", CC_CALLBACK_1 (TextureCacheTest :: loadingCallBack, this));
Director :: getInstance () -> getTextureCache () -> addImageAsync ("Images / grossini.png", CC_CALLBACK_1 (TextureCacheTest :: loadingCallBack, this));
Director :: getInstance () -> getTextureCache () -> addImageAsync ("Images / CloseNormal.png", CC_CALLBACK_1 (TextureCacheTest :: loadingCallBack, this));
....
}
// Função de retorno de chamada carregada de forma assíncrona
void TextureCacheTest :: loadingCallBack (cocos2d :: Texture2D * texture)
{
++ _ numberOfLoadedSprites;
char tmp [10];
sprintf (tmp, "%%% d", (int) (((float) _numberOfLoadedSprites / _numberOfSprites) * 100));
_labelPercent-> setString (tmp);
if (_numberOfLoadedSprites == _numberOfSprites)
{
this-> removeChild (_labelLoading, true);
this-> removeChild (_labelPercent, true);
addSprite ();
}
}
//
5. Limpe o cache
//
// Libere todas as texturas com uma contagem de referência de 1, ou seja, texturas que não estão sendo usadas no momento.
// Por exemplo, depois que uma nova cena é criada, é muito conveniente usar este método para liberar texturas não utilizadas.
Director :: getInstance () -> getTextureCache () -> removeUnusedTextures ();
// Exclua o mapa de textura do cache pelo nome-chave do mapa de textura fornecido
Director :: getInstance () -> getTextureCache () -> removeTextureForKey ("Images / grossinis.png");
// Limpa o registro de carregamento de mapas de textura. Se você receber um "aviso de memória", chame este método.
// A curto prazo: alguns arquivos de recursos serão lançados para evitar que seu aplicativo falhe
// A médio prazo: mais recursos serão alocados
// No longo prazo: nenhuma diferença
Director :: getInstance () -> getTextureCache () -> removeAllTextures ();
//
【SpriteFrameCache】
1. Visão Geral
SpriteFrameCache serve principalmente a imagem de textura mesclada de várias imagens quebradas. Este tipo de textura contém várias imagens pequenas em uma imagem grande, e será inconveniente referenciá-las diretamente através do TextureCache. Portanto, o método de processamento do frame do sprite é derivado, ou seja, a informação da textura interceptada é salva em um frame do sprite, e o sprite é trocado Quadros diferentes para mostrar padrões diferentes.
SpriteFrameCache encapsula um objeto Map _spriteFrames. (Onde chave é o nome do quadro)
SpriteFrameCache é geralmente usado para processar arquivos plist (este arquivo especifica a posição e tamanho de cada sprite individual nesta "grande imagem"), este arquivo corresponde a uma imagem grande contendo vários sprites, e o arquivo plist pode ser feito por TexturePacker .
A interface comum do SpriteFrameCache é semelhante ao TextureCache, então não vou entrar em detalhes.A única coisa que precisa ser notada é adicionar um arquivo plist e um grande mapa de textura para o quadro do sprite.
2. Obtenha e destrua SpriteFrameCache
SpriteFrameCache é um objeto singleton, então o método de aquisição é o mesmo do Director.
//
// Obter objeto singleton
SpriteFrameCache * cache = SpriteFrameCache :: getInstance ();
// Destrua o objeto singleton
SpriteFrameCache :: destroyInstance ();
//
3. Carregamento e uso de quadros de sprite
Carregue o arquivo plist por meio de addSpriteFramesWithFile e carregue várias imagens pequenas no arquivo plist no buffer de quadros sprite.
//
// Boy1.png e boy2.png são coletados em boy.png.
// O parâmetro 2 não pode ser escrito
SpriteFrameCache * frameCache = SpriteFrameCache :: getInstance ();
frameCache-> addSpriteFramesWithFile ("boy.plist", "boy.png");
// Encontre a imagem boy1.png no cache SpriteFrameCache.
auto frame_sp = Sprite :: createWithSpriteFrameName ("boy1.png");
this-> addChild (frame_sp, 2);
//
4. Limpe o cache
//
// Exclui um quadro de sprite do buffer de quadros de sprite.
SpriteFrameCache :: getInstance () -> removeSpriteFrameByName (const std :: string & name);
// Limpa o dicionário carregado no quadro do sprite. Se você receber "Aviso de memória", chame este método.
// Por enquanto: ele irá liberar alguns recursos para evitar que seu aplicativo falhe.
// Perspectiva de médio prazo: alocará mais recursos.
// No longo prazo: ele se tornará o mesmo.
SpriteFrameCache :: getInstance () -> removeSpriteFrames ();
// Remova vários frames de sprite de um arquivo .plist. Ou seja: os frames do sprite armazenados neste arquivo serão excluídos.
// É conveniente chamar este método quando uma textura particular precisa ser excluída.
SpriteFrameCache :: getInstance () -> removeSpriteFramesFromFile (const std :: string & plist);
// Remova todos os frames do sprite combinados com uma textura específica.
// É conveniente chamar este método quando uma textura particular precisa ser excluída.
SpriteFrameCache :: getInstance () -> removeSpriteFramesFromTexture (cocos2d :: Texture2D * texture);
// Remova frames inúteis de sprite. O quadro de sprite com o número reservado 1 será excluído.
// É conveniente chamar este método após iniciar uma nova cena.
SpriteFrameCache :: getInstance () -> removeUnusedSpriteFrames ();
//
5 、 SpriteFrameCache VS. TextureCache
SpriteFrameCache cache de quadro de sprite. Como o nome sugere, aqui está a moldura de sprite SpriteFrame, que serve principalmente a imagem de textura (arquivo plist) mesclada de várias imagens quebradas. Este tipo de textura contém várias imagens pequenas em uma imagem grande, e será inconveniente referenciá-las diretamente através do TextureCache. Portanto, o método de processamento do frame do sprite é derivado, ou seja, a informação da textura interceptada é salva em um frame do sprite, e o sprite é trocado Quadros diferentes para mostrar padrões diferentes.
Como a função TextureCache, o SpriteFrame é armazenado em cache e buscado diretamente na próxima vez que for usado.
No entanto, é diferente de TextureCache: se a imagem a ser pesquisada não existir no pool de memória, ele irá avisar que não pode ser encontrada, ao invés de carregar a imagem localmente.
> TextureCache é o cache de textura mais eficaz na camada inferior.O cache é o recurso de textura carregado na memória, ou seja, o recurso de imagem.
> SpriteFrameCache cache de quadro de sprite, o quadro de sprite de tempo armazenado em cache.
> SpriteFrameCache é um pacote baseado em TextureCache. A moldura do sprite em cache é um bloco retangular da área especificada da textura. Cada quadro de sprite está na mesma textura e diferentes padrões são exibidos alternando entre diferentes quadros.
【AnimationCache】
1. Visão Geral
Normalmente, para uma animação de sprite, você precisa carregar o frame do sprite toda vez que ele é criado, e então adicioná-los ao array em ordem, e então usar Animation para ler o array para criar a animação. Este é um processo de cálculo muito complicado. Para animações que são usadas com frequência, como personagens andando, dançando, etc., você pode adicioná-los ao AnimationCache e chamá-los deste cache sempre que os usar, o que pode reduzir efetivamente o enorme consumo de criação de animações.
Portanto, coloque a animação criada diretamente no cache de animação AnimationCache. Quando você precisar realizar uma ação de animação, pode retirá-la do cache de animação diretamente para criar e inicializar a animação.
2. Funções relacionadas
AnimationCache é um objeto singleton, portanto, o método de aquisição é o mesmo do Director.
Obtenha o objeto singleton por meio de AnimationCache :: getInstance ().
As funções relacionadas são as seguintes:
//
// Adicione uma animação ao cache e nomeie-a.
// nome-animação: é um conjunto de relacionamentos de pares de valores-chave (valor-chave).
void addAnimation (Animação * animação, const std :: string & name);
// Adicione o arquivo plist animado ao cache
void addAnimationsWithFile (const std :: string & plist);
// Obtenha a animação com o nome especificado como nome
Animação * getAnimation (const std :: string & name);
// Remove uma animação especificada
void removeAnimation (const std :: string & name);
//
3. Exemplos de uso
//
//
// A animação é chamada de Explosão e adicionada ao cache de animação
Animação * animação = Animação :: createWithSpriteFrames (arr, 0,04);
AnimationCache :: getInstance () -> addAnimation (animação, "Explosão");
// Buscar a animação "Explosão" diretamente do cache de animação
Animation * animation = AnimationCache :: getInstance () -> getAnimation ("Explosion");
//
//
【Ordem de limpeza】
Vale observar a ordem de limpeza.
Recomendamos a seguinte sequência de limpeza:
> Primeiro, limpe o cache de animação AnimationCache,
> Em seguida, limpe, SpriteFrameCache,
> Finalmente limpe, TextureCache.
Siga o nível de referência de alto para baixo para garantir que a liberação da referência seja válida.