菜鸟也能学cocos2dx3.0 浅析刀塔传奇(下)

首先我们讲点话外的东西,异步加载:众所周知,loading里面一般都是加载数据的,那么是怎么加载的呢?

Director::getInstance()->getTextureCache()->addImageAsync(const std::string &path, const std::function<void(Texture2D*)>& callback)//参数1,文件路径,参数2,回调函数(一般都是进度条)

那么如果我们要加载帧动画呢?

auto frameache=SpriteFrameCache::getInstance();
frameache->addSpriteFramesWithFile(" xxxxxx  ");//参数,plist文件路径

可是这样并不是异步加载,那么应该怎么办?其实还是用上面这两个:

Director::getInstance()->getTextureCache()->addImageAsync(const std::string &path, const std::function<void(Texture2D*)>& callback);//我们首先异步加载了纹理
auto My_Texture2D=Director::getInstance()->getTextureCache()->addImage(" ");

//如果我们成功异步加载图片之后,我们可以从纹理缓存里面,即std::unordered_map<std::string,Texture2D*> _textures  返回对应key的纹理。而key在引擎源代码中则是文件的完整路径,因为在texture2d里面会做一步std::string fullpath =FileUtils::getInstance()->fullPathForFilename(path);而我们外部用的话,只需要平时resources的路径即可。

或者直接auto cache=SpriteFrameCache::getInstance(); cache->addSpriteFramesWithFile("plist路径","png路径");

auto frameache=SpriteFrameCache::getInstance();
frameache->addSpriteFramesWithFile(" xxxxxx  ",My_Texture2D);//参数1,plist文件路径,参数2,纹理  这样我们就能完成异步加载帧动画了~

进入正题 刀塔传奇:

首先我们解压dota的包,会发现有


一张背景为黑色的jpg图和一张灰度图,对不是带alpha的png图,而是无alpha的jpg,那么刀塔传奇为什么要这么做呢?

以下为我个人的理解:

jpg图是将图像像素进行了压缩,而另外一张灰度图实际上则是附带了透明通道的8位的png,那么我们只要将灰度图的alpha复制过去,就能实现jpg的背景镂空。

这样的话就能缩小图片的资源大小,毕竟你jpg是经过压缩的,同等镂空的png果断是要大很多的,这里可以确定jpg+8位灰度<png。

那么这样做的优势在哪里呢,没错,就是在图片资源很多的情况下,我们可以清楚得感受到使用这种图片格式的好处:一、可以使你的应用程序更小,因为图片是压缩过了的。二、你的游戏能够启动地更快。

原理上和pvr.ccz有点类似,但是pvr.ccz有着它独特的优势,就是pvr格式可以直接被ios的显卡所认可,比png更加安全,避免大量图片加载的内存问题。

然后呢,我们应该怎么用jpg+灰度图实现纹理镂空的效果呢?

看引擎代码!

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

    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 Image();//创建一个image对象,imgae对象中封装了libjpeg,即jpg的解压/压缩库,另外利用了FileUtils::getInstance()->getDataFromFile(_filePath)  FileUtils默认会以rb模式读取二进制的数据信息
            CC_BREAK_IF(nullptr == image);

            bool bRet = image->initWithImageFile(fullpath);//将FileUtiles读取的数据用jpeg进行解压,期间有个图片格式的判断
            CC_BREAK_IF(!bRet);
		
            texture = new Texture2D();

            if( texture && texture->initWithImage(image) )//加载纹理将rgb888的jpg转为rgba8888
            {
#if CC_ENABLE_CACHE_TEXTURE_DATA
                // cache the texture file name
                VolatileTextureMgr::addImageTexture(texture, fullpath);
#endif
                // texture already retained, no need to re-retain it
                _textures.insert( std::make_pair(fullpath, texture) );
            }
            else
            {
                CCLOG("cocos2d: Couldn't create texture for file:%s in TextureCache", path.c_str());
            }
        } while (0);
    }

    CC_SAFE_RELEASE(image);

    return texture;
}
/*..
省略
*/

 *outDataLen = dataLen/3*4;//将rgb的length增长到rgba的长度
 *outData = new unsigned char[*outDataLen];//申请一块长度为rgba长度的内存
 auto TempData=outData;
/*..
省略
*/
 for (ssize_t i = 0, j=0,l = dataLen - 2; i < l; i += 3,++j)
    {
        * outData ++ = data[i];         //R
        * outData ++ = data[i + 1];     //G
        * outData ++ = data[i + 2];     //B
        * outData ++ =png_data[j];      //A 根据灰度图的像素信息0和255设置alpha
    }
auto new_Texture2d=new Texture2D();
new_Texture2d->initWithData(TempData,datalen,pixelFormat, imageWidth, imageHeight, imageSize);


//这样我们就能实现刀塔传奇的主界面效果。 至于主界面中的比如泉水发光的效果,则是通过shader实现的

至于dota的骨骼部分据说是他们自己的flash引擎做的,而我则用spine做了骨骼,因为cocostuio的骨骼功能不完善,spine则是专门针对骨骼的编辑器,并且全平台支持,u3d,libgdx,as3等等。最赞的应该就是spine的ffd,蒙皮了。

目前正在研究binary,即spine的二进制文件导出,直接读取binary创建骨骼的话,将会比json读取的更快,内存占用更小。

ps:cocos2dx 3.1rc0出了,支持prite3dvideo,目前感觉video应该是比较实用的,3d的话,个人感觉还是u3d吧。。。cocos3d支持还需要发展。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 17
    评论
评论 17
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值