Cocos2d-x 3.x aprendizado básico: três tipos de cache

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.

Acho que você gosta

Origin blog.csdn.net/qq_21743659/article/details/108595921
Recomendado
Clasificación