缓存机制

  • Cocos2d-x纹理缓存
  • Cocos2d-x精灵帧缓存
  • Cocos2d-x动画缓存

纹理缓存

事实上,当我们创建精灵时,引擎已经帮我们做了缓存,因而我们下次调用的图片可以从缓存获得,减少了内存的消耗,下面我们从源码入手,大致的了解创建精灵时,如何做纹理缓存。
实质上,纹理缓存类似一个字典库,而文件名就是索引的条件,我们可以根据文件名把图片缓存起来,也可以根据文件名获取缓存中的图片。
Sprite *grossini = Sprite::create("grossini_dance_01.png");<span style="white-space:pre">	</span>// 用图片创建精灵对象
接下来,转向精灵的create()函数的实现:
Sprite* Sprite::create(const std::string& filename)
{
    Sprite *sprite = new (std::nothrow) Sprite();<span style="white-space:pre">	</span>// 用C++的方式,创建一个精灵
    if (sprite && sprite->initWithFile(filename))<span style="white-space:pre">	</span>// 检查精灵对象,并进行文件初始化
    {
        sprite->autorelease();
        return sprite;
    }
    CC_SAFE_DELETE(sprite);<span style="white-space:pre">	</span>// 安全释放精灵对象
    return nullptr;
}
转向精灵文件初始化:
bool Sprite::initWithFile(const std::string& filename)
{
    CCASSERT(filename.size()>0,"Invalid filename for sprite");
    // 生成纹理图片
    Texture2D *texture = Director::getInstance()->getTextureCache()->addImage(filename);
    if (texture)
    {
        Rect rect = Rect::ZERO;
        rect.size = texture->getContentSize();
        return initWithTexture(texture,rect);<span style="white-space:pre">		</span>// 初始化纹理,将纹理图片进行添加
    }

    // don't release here.
    // when load texture Failed,it's better to get a "transparent" sprite then a crashed program
    // this->release();
    return false;
}

bool Sprite::initWithTexture(Texture2D *texture,const Rect& rect)
{
    return initWithTexture(texture,rect,false);<span style="white-space:pre">	</span>// 初始化纹理
}
转向初始化纹理initWithTexture(texture,rect):
<pre name="code" class="cpp">bool Sprite::initWithTexture(Texture2D *texture,const Rect& rect,bool rotated)
{
    bool result;
    if (Node::init())
    {
        ............
	............

        // 这里是关键点,将纹理图片设置添加到纹理缓存
        setTexture(texture);
	// 设置纹理矩形
        setTextureRect(rect,rotated,rect.size);
        
        _polyInfo.setQuad(&_quad);
        // by default use "Self Render".
        // if the sprite is added to a batchnode,then it will automatically switch to "batchnode Render"
        setBatchNode(nullptr);
        result = true;
    }
    else
    {
        result = false;
    }
    _recursiveDirty = true;
    setDirty(true);
    return result;
}
 
  继而查看将纹理图片设置添加到纹理缓存setTexture(texture);,其他的我们不需要注意,只需看如何将图片添加到纹理缓存: 
 
<pre name="code" class="cpp">void Sprite::setTexture(Texture2D *texture)
{
    // If batchnode,then texture id should be the same
    CCASSERT(! _batchNode || texture->getName() == _batchNode->getTexture()->getName(),"CCSprite: Batched sprites should use the same texture as the batchnode");
    // accept texture==nil as argument
    CCASSERT( !texture || dynamic_cast<Texture2D*>(texture),"setTexture expects a Texture2D. Invalid argument");

    if (texture == nullptr)
    {
        // 根据图片文件名,从纹理缓存中获取纹理图片
        texture = Director::getInstance()->getTextureCache()->getTextureForKey(CC_2x2_WHITE_IMAGE_KEY);

        // 如果获取内容为NULL,说明为缓存至纹理缓存
        if (texture == nullptr)
        {
            Image* image = new (std::nothrow) Image();
            bool isOK = image->initWithRawData(cc_2x2_white_image,sizeof(cc_2x2_white_image),2,8);
            CC_UNUSED_ParaM(isOK);
            CCASSERT(isOK,"The 2x2 empty texture was created unsuccessfully.");

	    // 根据图片文件名,将图片添加到纹理缓存
            texture = Director::getInstance()->getTextureCache()->addImage(image,CC_2x2_WHITE_IMAGE_KEY);
            CC_SAFE_RELEASE(image);
        }
    }

    if (!_batchNode && _texture != texture)
    {
        CC_SAFE_RETAIN(texture);
        CC_SAFE_RELEASE(_texture);
        _texture = texture;
        updateBlendFunc();
    }
}
 
  至此,我们就将图片添加到纹理缓存并创建了一个精灵对象。 
 
接下来,我们看一下如何添加纹理图片,转回
Texture2D *texture = Director::getInstance()->getTextureCache()->addImage(filename);
<pre name="code" class="cpp">Texture2D * TextureCache::addImage(const std::string &path)
{
    Texture2D * texture = nullptr;
    Image* image = nullptr;
    // Split up directory and filename
    // MUTEX:
    // Needed since addImageAsync calls this method from a different thread

    // 通过FileUtils::getInstance()->fullPathForFilename(path);获取完整的路径
    std::string fullpath = FileUtils::getInstance()->fullPathForFilename(path);
    if (fullpath.size() == 0)
    {
        return nullptr;
    }
    // 通过路径寻找纹理缓存中是否存在
    auto it = _textures.find(fullpath);
    if( it != _textures.end() )
        texture = it->second;
    // 如若不存在
    if (! texture)
    {
        // all images are handled by UIImage except PVR extension that is handled by our own handler
        do 
        {
            image = new (std::nothrow) Image();
            CC_BREAK_IF(nullptr == image);

            bool bRet = image->initWithImageFile(fullpath);
            CC_BREAK_IF(!bRet);

            texture = new (std::nothrow) Texture2D();
	    // 将图片添加转换成纹理
            if( texture && texture->initWithImage(image) )
            {
#if CC_ENABLE_CACHE_TEXTURE_DATA
                // 缓存纹理及文件名
                VolatileTextureMgr::addImageTexture(texture,fullpath);
#endif
                // _textures为纹理缓存字典,将纹理及路径插入到字典
                _textures.insert( std::make_pair(fullpath,texture) );

                //parse 9-patch info
                this->parseNinePatchImage(image,texture,path);
            }
            else
            {
                cclOG("cocos2d: Couldn't create texture for file:%s in TextureCache",path.c_str());
            }
        } while (0);
    }

    CC_SAFE_RELEASE(image);

    return texture;
}
 
 
精灵帧缓存

Cocos2d-x学习笔记十—— 缓存机制的更多相关文章

  1. 详解使用双缓存解决Canvas clearRect引起的闪屏问题

    这篇文章主要介绍了详解使用双缓存解决Canvas clearRect引起的闪屏问题的相关资料,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

  2. 利用Node实现HTML5离线存储的方法

    这篇文章主要介绍了利用Node实现HTML5离线存储的方法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

  3. HTML5 Web缓存和运用程序缓存(cookie,session)

    这篇文章主要介绍了HTML5 Web缓存和运用程序缓存(cookie,session),小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

  4. 详解前端HTML5几种存储方式的总结

    本篇文章主要介绍了前端HTML5几种存储方式的总结 ,主要包括本地存储localstorage,本地存储sessionstorage,离线缓存(application cache),Web SQL,IndexedDB。有兴趣的可以了解一下。

  5. 在iOS上,缓存绘制的屏幕图像并显示它的最快方法是什么?

    我没有让drawRect每次重绘数千个点,我认为有几种方法可以“在屏幕上缓存图像”和任何其他绘图,我们将添加到该图像,并在drawRect时显示该图像:>使用BitmapContext并绘制到位图,并在drawRect中绘制此位图.>使用CGLayer并在drawRect中绘制CGLayer,这可能比方法1快,因为此图像缓存在图形卡中(并且它不会计入iOS上“内存警告”的RAM使用情况?

  6. ios – NSURLCache和数据保护

    我正在尝试保护存储在NSURLCache中的敏感数据.我的应用程序文件和CoreDatasqlite文件设置为NSFileProtectionComplete.但是,我无法将NSURLCache文件数据保护级别更改为NSFileProtectionCompleteUntilFirstUserAuthentication以外的任何其他级别.这会在设备锁定时暴露缓存中的任何敏感数据.我需要缓存响应,以

  7. iOS Safari多久会清除一次缓存?

    我使用移动Safari缓存来存储我想要持久化的一些数据,所以我希望它们能够在Safari重启和iOS重启后继续存在.但是我已经阅读了somenew和someold报告,Safari在Safari重新启动时清除了它的缓存.但我对Safari8.3的非科学测试表明,有时这个缓存实际上不仅可以在应用程序重启后生存,而且甚至可以重启iOS(!).所以我在这一点上有点困惑.iOSSafari缓存清除的规则是否记录在某处?你们中有谁知道他们并且可以向我解释他们吗?解决方法希望有人发现我错了但是……

  8. ios – 如何获取缓存图像SDWebImage的数据

    我正在使用SDWebImage库来缓存我的UICollectionView中的Web图像:但我想将缓存的图像本地保存在文件中,而不是再次下载它们有没有办法获取缓存图像的数据解决方法SDWebImage默认自动缓存下载的图像.您可以使用SDImageCache从缓存中检索图像.当前应用会话有一个内存缓存,它会更快,并且有磁盘缓存.用法示例:还要确保在文件中导入SDWebImage.(如果您使用的是Swift/Carthage,它将导入WebImage

  9. 缓存 – NSURLCache在iOS5上提供不一致的结果,似乎是随机的

    我刚刚花了很长时间在NSURLCache尖叫我,所以我提供了一些建议,希望别人能够避免我的不幸.这一切都足够合理.我的新应用程序项目只针对iOS5及更高版本,所以我认为我可以利用新的NSURLCache实现我所有的Web缓存需求.我需要一个NSURLCache的自定义子类来处理一些特殊的任务,但是这似乎都被API的有力支持.快速阅读文档,我会参加比赛:我认为一个8MB缓存启动是很好的,我会用更大的

  10. iOS与解析. PFUser.currentuser()没有缓存.应用程序重新启动后返回零

    我正在迅速地用Parse构建一个应用程序.在应用程序停止后,PFUser.currentuser()总是返回nil,并再次运行.我正在使用iOS模拟器,并且启用了本地数据存储.我正在使用这样的东西–而我正在使用的登录当前用户保持到应用程序重新启动,然后重置为零.我甚至试图固定当前用户,但它不起作用.如何检查当前用户是否在本地缓存.任何帮助将不胜感激.谢谢.解决方法对我来说,原因只是以下部分没有执行.注意多线程.通常是这个原因.

随机推荐

  1. 【cocos2d-x 3.x 学习笔记】对象内存管理

    Cocos2d-x的内存管理cocos2d-x中使用的是上面的引用计数来管理内存,但是又增加了一些自己的特色。cocos2d-x中通过Ref类来实现引用计数,所有需要实现内存自动回收的类都应该继承自Ref类。下面是Ref类的定义:在cocos2d-x中创建对象通常有两种方式:这两中方式的差异可以参见我另一篇博文“对象创建方式讨论”。在cocos2d-x中提倡使用第二种方式,为了避免误用第一种方式,一般将构造函数设为protected或private。参考资料:[1]cocos2d-x高级开发教程2.3节[

  2. 利用cocos2dx 3.2开发消灭星星六如何在cocos2dx中显示中文

    由于编码的不同,在cocos2dx中的Label控件中如果放入中文字,往往会出现乱码。为了方便使用,我把这个从文档中获取中文字的方法放在一个头文件里面Chinese.h这里的tex_vec是cocos2dx提供的一个保存文档内容的一个容器。这里给出ChineseWords,xml的格式再看看ChineseWord的实现Chinese.cpp就这样,以后在需要用到中文字的地方,就先include这个头文件然后调用ChineseWord函数,获取一串中文字符串。

  3. 利用cocos2dx 3.2开发消灭星星七关于星星的算法

    在前面,我们已经在GameLayer中利用随机数初始化了一个StarMatrix,如果还不知道怎么创建星星矩阵请回去看看而且我们也讲了整个游戏的触摸事件的派发了。

  4. cocos2dx3.x 新手打包APK注意事项!

    这个在编译的时候就可以发现了比较好弄这只是我遇到的,其他的以后遇到再补充吧。。。以前被这两个问题坑了好久

  5. 利用cocos2dx 3.2开发消灭星星八游戏的结束判断与数据控制

    如果你看完之前的,那么你基本已经拥有一个消灭星星游戏的雏形。开始把剩下的两两互不相连的星星消去。那么如何判断是GameOver还是进入下一关呢。。其实游戏数据贯穿整个游戏,包括星星消除的时候要加到获得分数上,消去剩下两两不相连的星星的时候的加分政策等,因此如果前面没有做这一块的,最好回去搞一搞。

  6. 利用cocos2dx 3.2开发消灭星星九为游戏添加一些特效

    needClear是一个flag,当游戏判断不能再继续后,这个flag变为true,开始消除剩下的星星clearSumTime是一个累加器ONE_CLEAR_TIME就是每颗星星消除的时间2.连击加分信息一般消除一次星星都会有连击信息和加多少分的信息。其实这些combo标签就是一张图片,也是通过控制其属性或者runAction来实现。源码ComboEffect.hComboEffect.cpp4.消除星星粒子效果消除星星时,为了实现星星爆裂散落的效果,使用了cocos2d提供的粒子特效引擎对于粒子特效不了

  7. 02 Cocos2D-x引擎win7环境搭建及创建项目

    官网有搭建的文章,直接转载记录。环境搭建:本文介绍如何搭建Cocos2d-x3.2版本的开发环境。项目创建:一、通过命令创建项目前面搭建好环境后,怎样创建自己的Cocos2d-x项目呢?先来看看Cocos2d-x3.2的目录吧这就是Cocos2d-x3.2的目录。输入cocosnew项目名–p包名–lcpp–d路径回车就创建成功了例如:成功后,找到这个项目打开proj.win32目录下的Hello.slnF5成功了。

  8. 利用cocos2dx 3.2开发消灭星星十为游戏添加音效项目源码分享

    一个游戏,声音也是非常的重要,其实cocos2dx里面的简单音效引擎的使用是非常简单的。我这里只不过是用一个类对所有的音效进行管理罢了。Audio.hAudio.cpp好了,本系列教程到此结束,第一次写教程如有不对请见谅或指教,谢谢大家。最后附上整个项目的源代码点击打开链接

  9. 03 Helloworld

    程序都有一个入口点,在C++就是main函数了,打开main.cpp,代码如下:123456789101112131415161718#include"main.h"#include"AppDelegate.h"#include"cocos2d.h"USING_NS_CC;intAPIENTRY_tWinMain{UNREFERENCED_ParaMETER;UNREFERENCED_ParaMETER;//createtheapplicationinstanceAppDelegateapp;return

  10. MenuItemImage*图标菜单创建注意事项

    学习cocos2dx,看的是cocos2d-x3.x手游开发实例详解,这本书错误一大把,本着探索求知勇于发现错误改正错误的精神,我跟着书上的例子一起调试,当学习到场景切换这个小节的时候,出了个错误,卡了我好几个小时。

返回
顶部