Cocos2d-x 3.x basic learning: three types of cache

The Cocos engine mainly has three types of cache, which are texture cache, sprite frame cache and animation cache. which is:

> Texture cache: TextureCache

> Sprite Frame Cache: SpriteFrameCache

> Animation cache: AnimationCache

The purpose of caching is to load the required resources (such as texture images) into the memory first, and then when the resources are used again, they can be directly taken out of the memory without reloading. Thereby reducing the memory usage of CPU and GPU.

This article sorts out and integrates the content of the references, and adds some of its own opinions.

【TextureCache】

1 Overview

      A lot of texture images need to be loaded in the game, and these operations are very memory and resource consuming.

       When there is an interface in the game that uses a lot of pictures, the speed is very slow when the interface is clicked for the first time (because there are many pictures to be loaded and drawn), we can use TextureCache to asynchronously load the texture in advance, and when the loading is over, enter It will be very fast to use these pictures on this interface.

> Texture2D (texture): the texture object for CPU and GPU operation after the picture is loaded into the memory.

> TextureCache (texture cache): used to load and manage textures. Once the texture is loaded, it can be used next time to return to the previously loaded texture, thereby reducing the memory usage of GPU and CPU.

       When you create a sprite, you usually use Sprite::create(fileName). If you look at the implementation of Sprite::create(fileName), you will see that it adds this image to the texture cache.

//

Sprite* Sprite::create(const std::string& filename)

{

Sprite *sprite = new Sprite();

if (sprite && sprite->initWithFile(filename))

{

sprite->autorelease();

return sprite;

}

_SAFE_DELETE(sprite);

return nullptr;

}

bool Sprite::initWithFile(const std::string& filename)

{

ASSERT(filename.size()>0, "Invalid filename for sprite");

// Load the texture image of filename

Texture2D *texture = Director::getInstance()->getTextureCache()->addImage(filename);

if (texture)

{

Rect rect = Rect::ZERO;

rect.size = texture->getContentSize();

return initWithTexture(texture, rect);

}

return false;

}

//

2. Get TextureCache

In the 3.x version, TextureCache is no longer used as a singleton mode. Instead, it is used as a member variable of the Director and obtained in the following way.

//

// Get the texture cache class TextureCache

Director::getInstance()->getTextureCache();

//

3. Loading and obtaining texture

If the file name has not been loaded before, it will create a new Texture2D object and it will return it. It will use the file name as the key otherwise, it will return a reference to the previously loaded image.

> addImage: The function will return a reference to the texture Texture2D, which may be newly loaded into the memory, or it may already exist before.

> getTextureForKey: Get the texture cache corresponding to this key. If the texture corresponding to this key does not exist, then nullptr is returned.

> The supported image formats are: .png, .bmp, .tiff, .jpeg, .pvr.

//

// addImage loads texture images

// Support image formats: .png, .bmp, .tiff, .jpeg, .pvr

Texture2D *texture = Director::getInstance()->getTextureCache()->addImage(filename);

// getTextureForKey Get texture image

Texture2D *texture = Director::getInstance()->getTextureCache()->getTextureForKey(textureKeyName);

//

4. Load texture asynchronously

The TextureCache class also supports the function of asynchronously loading resources, using the addImageAsync method. You can add a callback method to the addImageAsync method, so that you can be notified when the asynchronous loading of the texture ends.

> The supported image formats are: .png, .jpg.

You can choose asynchronous loading mode, so you can add a progress bar to the loading scene.

The key code is as follows:

//

TextureCacheTest :: TextureCacheTest ()

: _numberOfSprites(20)

, _numberOfLoadedSprites(0)

{

auto size = Director::getInstance()->getWinSize();

_labelLoading = Label::createWithTTF("loading...", "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);

// Load texture image asynchronously addImageAsync

// After loading the texture, the callback function will be executed

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));

....

}

// Asynchronously loaded callback function

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. Clean the cache

//

// Release all textures with a reference count of 1, that is, textures that are not currently being used.

// For example, after a new scene is created, it is very convenient to use this method to release unused textures.

Director::getInstance()->getTextureCache()->removeUnusedTextures();

// Delete the texture map from the cache by the key name of the given texture map

Director::getInstance()->getTextureCache()->removeTextureForKey("Images/grossinis.png");

// Clear the record of loading texture maps. If you receive a "memory warning", please call this method.

// In the short term: some resource files will be released to prevent your app from crashing

// In the medium term: more resources will be allocated

// In the long run: no difference

Director::getInstance()->getTextureCache()->removeAllTextures();

//

【SpriteFrameCache】

1 Overview

SpriteFrameCache mainly serves the texture picture merged from multiple broken pictures. This kind of texture contains multiple small images in a large image, and it will be inconvenient to directly reference them through TextureCache. Therefore, the processing method of the sprite frame is derived, that is, the intercepted texture information is saved in a sprite frame, and the sprite is switched Different frames to show different patterns.

SpriteFrameCache encapsulates a Map _spriteFrames object. (Where key is the name of the frame)

SpriteFrameCache is generally used to process plist files (this file specifies the position and size of each individual sprite in this "big picture"), this file corresponds to a large picture containing multiple sprites, and the plist file can be made by TexturePacker .

The common interface of SpriteFrameCache is similar to TextureCache, so I won't go into details. The only thing that needs to be noticed is to add a plist file and a large texture map for the sprite frame.

2. Obtain and destroy SpriteFrameCache

SpriteFrameCache is a singleton object, so the acquisition method is the same as that of Director.

//

// Get singleton object

SpriteFrameCache* cache = SpriteFrameCache::getInstance();

// Destroy the singleton object

SpriteFrameCache::destroyInstance();

//

3. Loading and use of sprite frames

Load the plist file through addSpriteFramesWithFile, and load multiple small pictures in the plist file into the sprite frame buffer.

//

// Boy1.png and boy2.png are collected in boy.png.

// Parameter 2 can not be written

SpriteFrameCache *frameCache = SpriteFrameCache::getInstance();

frameCache->addSpriteFramesWithFile("boy.plist", "boy.png");

//Find the picture boy1.png from the SpriteFrameCache cache.

auto frame_sp = Sprite::createWithSpriteFrameName("boy1.png");

this->addChild(frame_sp, 2);

//

4. Clean the cache

//

// Delete a sprite frame from the sprite frame buffer.

SpriteFrameCache::getInstance()->removeSpriteFrameByName(const std::string &name);

// Clear the dictionary loaded into the sprite frame. If you receive "Memory Warning", please call this method.

// For the moment: it will release some resources to prevent your app from crashing.

// Mid-term perspective: it will allocate more resources.

// In the long run: it will become the same.

SpriteFrameCache::getInstance()->removeSpriteFrames();

// Remove multiple sprite frames from a .plist file. That is: the sprite frames stored in this file will be deleted.

// It is convenient to call this method when a particular texture needs to be deleted.

SpriteFrameCache::getInstance()->removeSpriteFramesFromFile(const std::string &plist);

// Remove all sprite frames combined with a specific texture.

// It is convenient to call this method when a particular texture needs to be deleted.

SpriteFrameCache::getInstance()->removeSpriteFramesFromTexture(cocos2d::Texture2D *texture);

// Remove useless sprite frames. The sprite frame with the reserved number 1 will be deleted.

// It is convenient to call this method after starting a new scene.

SpriteFrameCache::getInstance()->removeUnusedSpriteFrames();

//

5、SpriteFrameCache VS. TextureCache

SpriteFrameCache sprite frame frame cache. As the name suggests, here is the sprite frame SpriteFrame, which mainly serves the texture picture (plist file) merged from multiple broken pictures. This kind of texture contains multiple small images in a large image, and it will be inconvenient to directly reference them through TextureCache. Therefore, the processing method of the sprite frame is derived, that is, the intercepted texture information is saved in a sprite frame, and the sprite is switched Different frames to show different patterns.

Like the TextureCache function, the SpriteFrame is cached and fetched directly the next time it is used.

However, it is different from TextureCache: if the image to be searched does not exist in the memory pool, it will prompt that it cannot be found, instead of loading the image locally.

> TextureCache is the most effective texture cache at the bottom layer. The cache is the texture resource loaded into the memory, that is, the image resource.

> SpriteFrameCache sprite frame frame cache, the cached time sprite frame.

> SpriteFrameCache is a package based on TextureCache. The cached sprite frame is a rectangular block of the specified area of ​​the texture. Each sprite frame is in the same texture, and different patterns are displayed by switching between different frames.

【AnimationCache】

1 Overview

Normally, for a sprite animation, you need to load the sprite frame every time it is created, and then add them to the array in order, and then use Animation to read the array to create the animation. This is a very cumbersome calculation process. For animations that are frequently used, such as characters walking, dancing, etc., you can add them to the AnimationCache, and call them from this cache every time you use them, which can effectively reduce the huge consumption of creating animations.

So put the created animation directly in the animation cache AnimationCache. When you need to perform an animation action, you can take it out of the animation cache directly to create and initialize the Animation.

2. Related functions

AnimationCache is a singleton object, so the acquisition method is the same as that of Director.

Get the singleton object through AnimationCache::getInstance().

The related functions are as follows:

//

// Add an animation to the cache and name it name.

// name-animation: is a set of key-value pairs (key-value) relationship.

void addAnimation(Animation *animation, const std::string& name);

// Add the animated plist file to the cache

void addAnimationsWithFile(const std::string& plist);

// Get the animation with the specified name as name

Animation* getAnimation(const std::string& name);

// Remove a specified animation

void removeAnimation(const std::string& name);

//

3. Examples of use

//

//

//The animation is named Explosion and added to the animation cache

Animation* animation = Animation::createWithSpriteFrames(arr, 0.04);

AnimationCache::getInstance()->addAnimation(animation, "Explosion");

//Fetch the "Explosion" animation directly from the animation cache

Animation* animation = AnimationCache::getInstance()->getAnimation("Explosion");

//

//

【Cleaning order】

It is worth noting the order of cleaning.

We recommend the following cleaning sequence:

> First clean up, animation cache AnimationCache,

> Then clean up, SpriteFrameCache,

> Finally clean up, TextureCache.

Follow the reference level from high to low to ensure that the release of the reference is valid.

Guess you like

Origin blog.csdn.net/qq_21743659/article/details/108595921