聊聊如何使用一套csb进行多语言匹配

聊聊csd 和csb

虽然cocos已经抛弃cocostudio了,不过考虑到现有项目依然在使用它,所以还是说说吧。
先说说FlatBuffers吧。
+ 概述

Google在2014年6月份发布了跨平台序列化工具FlatBuffers,提供了C++/Java/Go/C#接口支持,这是一个注重性能和资源使用的序列化类库。相较于Protocol Buffers,其更适用于移动设备,FlatBuffers提供更高的性能以及更低的资源需求。
+ 特点
1. 不需要打包/解包。它的结构化数据都以二进制形式保存,不需要数据解析过程,数据也可以方便传递
2. 省内存、性能好
3. 强类型系统,在编译阶段就能预防一些bug的产生
4. 跨平台(C++11/Java/Go/C#)

FlatBuffers跟cab有什么关系?因为csd使用FlatBuffers转换成cab。

先看下csd里面写了些什么。
<GameProjectFile>
<PropertyGroup Type="Node" Name="test" ID="ca42dc96-1bb8-4067-a0ce-b2b4d6515b20" Version="2.3.0.1" />
<Content ctype="GameProjectContent">
<Content>
<Animation Duration="0" Speed="1.0000" />
<ObjectData Name="Node" ctype="GameNodeObjectData">
<Size />
<Children>
<AbstractNodeData Name="UI_3024_abubing_1" ActionTag="-947478463" Tag="2" IconVisible="False" LeftMargin="88.5000" RightMargin="-183.5000" TopMargin="-110.5000" BottomMargin="63.5000" ctype="SpriteObjectData">
<Size X="95.0000" Y="47.0000" />
<AnchorPoint ScaleX="0.5000" ScaleY="0.5000" />
<Position X="136.0000" Y="87.0000" />
<Scale ScaleX="1.0000" ScaleY="1.0000" />
<CColor A="255" R="255" G="255" B="255" />
<PrePosition />
<PreSize />
<FileData Type="PlistSubImage" Path="UI_3024_abubing.png" Plist="texture/ui/BY/BYbingying.plist" />
<BlendFunc Src="1" Dst="771" />
</AbstractNodeData>
</Children>
</ObjectData>
</Content>
</Content>
</GameProjectFile>

一目了然,树装结构,没什么好说的。
那么csb那:
1400 0000 1000 1c00 0400 0800 0c00 1000
1400 1800 1000 0000 4c00 0000 1c00 0000
1400 0000 4c00 0000 f439 0000 0400 0000
0000 0000 0000 0000 0a00 0000 381b 0000
b018 0000 d414 0000 7c12 0000 4010 0000
880c 0000 4c0a 0000 9406 0000 5804 0000
1c02 0000 0700 0000 322e 312e 302e 3000
完全不知道是什么了。

问题描述:语言包
1、最近要接国外项目,需要语言包。美术资源将原有的美术字从png里分离,放入指定文件夹里。问题是csd,如果每个csd都使用cocostudio来一遍,那真是噩梦啊。

所以我们使用脚本,批量修改了Type=”PlistSubImage” Plist属性。

2、放入程序后,发现如果美术字的大小发生变化,会出现显示的异常。

没办法了,扒源码吧。

CSLoader.cpp

Node* CSLoader::nodeWithFlatBuffersFile(const std::string &fileName)
{
    std::string fullPath = FileUtils::getInstance()->fullPathForFilename(fileName);

    Data buf = FileUtils::getInstance()->getDataFromFile(fullPath);
    ......
    auto csparsebinary = GetCSParseBinary(buf.getBytes());
    // decode plist
    auto textures = csparsebinary->textures();
    int textureSize = csparsebinary->textures()->size();
    //    CCLOG("textureSize = %d", textureSize);
    for (int i = 0; i < textureSize; ++i)
    {
        SpriteFrameCache::getInstance()->addSpriteFramesWithFile(textures->Get(i)->c_str());        
    }
    Node* node = nodeWithFlatBuffers(csparsebinary->nodeTree());
    return node;
}

很明显GetCSParseBinary(buf.getBytes())就是cab的解析。这里不多做介绍了。接续追nodeWithFlatBuffers

    std::string readername = getGUIClassName(classname);
    readername.append("Reader");
    NodeReaderProtocol* reader = dynamic_cast<NodeReaderProtocol*>(ObjectFactory::getInstance()->createObject(readername));
    node = reader->createNodeWithFlatBuffers(options->data());

上面的代码是根据node的类型匹配不同的rander对节点进行解析,美术字是sprite,所以我们会进入SpriteRander。SpriteRander解析sprite属性或会调用NodeRander解析node属性。这里我们发现csd中<Size X="95.0000" Y="47.0000" />是不会改变的,也就是说是个死值。(为什么不根据plist的大小去匹配?估计是考虑到九宫吧)果然在NodeRander中

float w             = options->size()->width();
float h             = options->size()->height();

果然取的是<size>里的值。相当于我们使用了一个size(100,100)的texture,但是csd确认为他的content size是size(50,50)。

找到问题就好办了,由于我们的美术字放在特定的文件夹里,所以只需在SpriteRander中取frame的rect,并将值传入NodeRander,nodeRander的w,h使用传入的值即可。测试后发现,修改后的代码比较满足我们的要求。

最后说说开源吧,开源的东西怎么说那,各种问题各种有,不过好处就是一切都是明明白白的,要怪就怪你没那个水平,看不懂罢了。看得懂了,想怎么改就怎么改。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值