关于图集atlas的使用

刚接触crator不久,原来使用过c++版本的cocos2d-x,也用过cocos code ide,习惯了旧的方法,想仿照spriteframecache的使用方法写一个工具类,实现通过图集内某一张小图的名称获取精灵帧

如下代码:

var loadAtlas = {
    spriteFrameArray : [],
    load: function() {
        
    },
    //导入一个资源
    loadAtlasRes: function(atlasUrl, callBack) {
        var self = this;
        cc.loader.loadRes(atlasUrl, cc.SpriteAtlas, function(err, atlas) {
            //精灵帧数组
            var resArray = atlas.getSpriteFrames();
            for (var i = 0; i < resArray.length; i++) {
                var spriteFrame = resArray[i];
                self.spriteFrameArray[spriteFrame.name] = spriteFrame;
            }
            callBack();
        });
    },
    //导入多个资源
    loadAtlasResAll: function(atlasUrl, callBack) {
        
    },
    //释放一个资源
    releaseAtlasRes: function(atlasUrl) {
        
    },
    //释放多个资源
    releaseAtlasResAll: function(atlasUrl) {
        
    },
    //通过名字获取一个精灵帧
    getSpriteFrameFromName: function(spriteFrameName) {
        return this.spriteFrameArray[spriteFrameName];
    }
};

loadAtlas.load();
module.exports = loadAtlas;

另一个组件内:

     func: function() {
        
        var self = this;
        var loadAtlas = require("loadAtlas");
        loadAtlas.loadAtlasRes("role/sp_all", function() {
            self.test();
        })
        
    },
    test: function() {
        var loadAtlas = require("loadAtlas");
        var node = new cc.Node();
        node.setPosition(50,50);
        node.parent = this.node;
        var sprite = node.addComponent(cc.Sprite);
        sprite.spriteFrame = loadAtlas.getSpriteFrameFromName("enemy1");
    }

目前可以这样使用
这样写完可能使用方便了,不过也有问题,如果两个图集内有名称相同的小图有一个会被覆盖,没想到什么好的解决方法,另外不知道哪里能够看到cc.loader.loadResAll的源码啊,想仿照一下,写批量加载的

1赞

单独的数组来索引所有的 spriteFrame 一定会遇到名字冲突的问题,可以考虑加上 atlas 名称作为前缀,比如 ‘sp_all/enemy1’ 来索引 spriteFrame,但仍然有可能遇到不同文件夹下的同名 atlas 文件 + 同名 frame 的冲突。

这也是我们用 cc.loader 来管理所有 atlas 资源的原因之一,在 loader 中,以唯一的 url 为索引来管理所有资源,提供方法通过 uuid / url 来访问资源,不会出现资源的名字冲突问题。

另外一个重要的原因是,如果严格遵循只有 loader 管理资源的方式,引擎对于资源的释放和加载可以更加有效,你这样的方式会导致 loader 外对于资源的引用,就需要严格进行管理了,而 loader 对于资源的 release 操作也可能会失效。

事实上,对于资源,在编辑器上可以很友好得管理依赖,一般不需要全局的引用,在需要的组件中,添加好 atlas 属性依赖,这样也更严谨。

最后,loadResAll 已经被改名为更加严谨的 loadResDir,实现在这里

https://github.com/cocos-creator/engine/blob/v1.4/cocos2d/core/load-pipeline/CCLoader.js#L440

那么,这种异步加载的方式是不能避免了吧,即便是已经使用了
cc.loader.loadRes(){}
这个方法导入了资源,在需要时用的地方还是需要通过
cc.loader.loadRes(){}
这个方法,因为需要回调函数中的atlas对象去获得某个精灵帧的名称,没有别的方法吧
那么我可以在js文件中保存下这些atlas对象在后面的组件去使用吗

你误解了,load 是用来加载的,所以是异步没错,但是获取是可以同步获取的

var atlas = cc.loader.getRes(url, cc.SpriteAtlas);
1赞

哦,谢谢,这样明白了

还有个小疑问,关于加载资源这个方法中的参数type,cc.SpriteFrame和cc.SpriteAtlas有什么区别啊,如果仅仅只是载入而不再回调中使用感觉没有区别吧

cc.SpriteAtlas 获取到的是图集资源,如果用 cc.SpriteFrame 获取到的是完整合图对应的大的 SpriteFrame,如果不指定类型,获取的是 Texture2D 资源

請問大大,spine[atlas and json and png] or [plist and json] 是可以從線上下載直接使用的嗎?

这么说 那是用cc.SpriteAtlas会更节约性能了?可以这样理解嘛

1赞