CocosCreator Label优化

1.需要修改引擎,参阅引擎定制工作流程

2.BITMAP缓存优化原理,参阅【乐府】突破Label的缓存模式之(1) BITMAP - Creator - Cocos中文社区

3.查看动态合图的api

运行时在console中输入

开启

cc.dynamicAtlasManager.showDebug(true);

关闭

cc.dynamicAtlasManager.showDebug(false);

4.修改记录

cocos2d/core/renderer/utils/label/ttf.js


_calDynamicAtlas (comp) {

        if(comp.cacheMode !== Label.CacheMode.BITMAP) return;

        let frame = comp._frame;

        // Delete cache in atlas.

        // mrlizs

        // deleteFromDynamicAtlas(comp, frame);

        if (!frame._original) {

            frame.setRect(cc.rect(0, 0, _canvas.width, _canvas.height));

        }

        // mrlizs

        // 给frame的texture计算一个新的_uuid值

        frame._texture._uuid = comp.string + "_" + comp.node.color + "_" + comp.fontSize + comp.fontFamily;

        this.packToDynamicAtlas(comp, frame);

    }

cocos2d/core/renderer/utils/utils.js

deleteFromDynamicAtlas (comp, frame) {

        if (frame && !CC_TEST) {

            if (frame._original && dynamicAtlasManager) {

                // mrlizs

                // dynamicAtlasManager.deleteAtlasSpriteFrame(frame);

                frame._resetDynamicAtlasFrame();

            }

        }

    }

cocos2d/core/renderer/utils/dynamic-atlas/atlas.js

insertSpriteFrame (spriteFrame) {

        let rect = spriteFrame._rect,

            texture = spriteFrame._texture;

            // mrlizs

            // info = this._innerTextureInfos[texture._id];

        // 在这里通过_uuid来判断重用性

        // this._dynamicTextureRect 增加的一个字典用来记录uuid与texture的映射关系

        let info = this._dynamicTextureRect[texture._uuid];

        let sx = rect.x, sy = rect.y;

        if (info) {

            sx += info.x;

            sy += info.y;

        }

        else {

            let width = texture.width, height = texture.height;        

            if ((this._x + width + space) > this._width) {

                this._x = space;

                this._y = this._nexty;

            }

            if ((this._y + height + space) > this._nexty) {

                this._nexty = this._y + height + space;

            }

            if (this._nexty > this._height) {

                return null;

            }

            // texture bleeding

            if (cc.dynamicAtlasManager.textureBleeding) {

                // Smaller frame is more likely to be affected by linear filter

                if (width <= 8 || height <= 8) {

                    this._texture.drawTextureAt(texture, this._x-1, this._y-1);

                    this._texture.drawTextureAt(texture, this._x-1, this._y+1);

                    this._texture.drawTextureAt(texture, this._x+1, this._y-1);

                    this._texture.drawTextureAt(texture, this._x+1, this._y+1);

                }

                this._texture.drawTextureAt(texture, this._x-1, this._y);

                this._texture.drawTextureAt(texture, this._x+1, this._y);

                this._texture.drawTextureAt(texture, this._x, this._y-1);

                this._texture.drawTextureAt(texture, this._x, this._y+1);

            }

            this._texture.drawTextureAt(texture, this._x, this._y);

            this._innerTextureInfos[texture._id] = {

                x: this._x,

                y: this._y,

                texture: texture

            };

            // mrlizs

            this._dynamicTextureRect[texture._uuid] = {

                x: this._x,

                y: this._y

            };

            this._count++;

            sx += this._x;

            sy += this._y;

            this._x += width + space;

            this._dirty = true;

        }

        let frame = {

            x: sx,

            y: sy,

            texture: this._texture

        }

        

        this._innerSpriteFrames.push(spriteFrame);

        return frame;

    },

    // mrlizs

    fetchSpriteFrame(spriteFrame) {

        let texture = spriteFrame._texture;

        let info = this._dynamicTextureRect[texture._uuid];

        if (!info) {

            return null;

        }    

        let rect = spriteFrame._rect;

        let sx = rect.x + info.x, sy = rect.y + info.y;

        let frame = {

                x: sx,

                y: sy,

                texture: this._texture

            }

        if (!this._innerSpriteFrames.includes(spriteFrame)) {

            this._innerSpriteFrames.push(spriteFrame);

        }

        return frame;

    },

    deleteInnerTexture (texture) {

        if (texture && this._innerTextureInfos[texture._id]) {

            delete this._innerTextureInfos[texture._id];

            // mrlizs

            delete this._dynamicTextureRect[texture._uuid];

            for(let i = 0, n = this._innerSpriteFrames.length; i < n; i++){

                if (this._innerSpriteFrames[i]._texture._uuid == texture._uuid){

                    this._innerSpriteFrames.splice(i,1);

                    break;

                }

            }

            this._count--;

        }

    }

cocos2d/core/renderer/utils/dynamic-atlas/manager.js

insertSpriteFrame(spriteFrame) {

        if (CC_EDITOR) return null;

        if (!_enabled || _atlasIndex === _maxAtlasCount ||

            !spriteFrame || spriteFrame._original) return null;

        if (!spriteFrame._texture.packable) return null;

        // mrlizs

        for (let i = 0, n = _atlases.length; i < n; i++) {

            let atlas = _atlases[i];

            // 如果能从当前图集中找到相同_uuid的图集块,则重用

            let frame = atlas.fetchSpriteFrame(spriteFrame);

            if (frame != null) return frame;

        }

        let atlas = _atlases[_atlasIndex];

        if (!atlas) {

            atlas = newAtlas();

        }

        let frame = atlas.insertSpriteFrame(spriteFrame);

        if (!frame && _atlasIndex !== _maxAtlasCount) {

            atlas = newAtlas();

            return atlas.insertSpriteFrame(spriteFrame);

        }

        return frame;

    }

5.效果

修改前,原引擎对label的缓存是在onEnable时都会把上一次已缓存的纹理清掉然后重新创建,而实际上动态合图里有大量重复的label纹理,运行cc.dynamicAtlasManager.showDebug(true);

时可以看到合图内容。

修改后,首先不再清掉动态合图里的缓存纹理,然后label的纹理会先去动态合图中找已经存在的图块,如果存在则复用,不存在再创建。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是一些常见的Cocos Creator面试题: 1. 什么是Cocos CreatorCocos Creator是一个基于JavaScript、TypeScript和HTML5技术的2D游戏开发引擎,它提供了一个可视化的编辑器,让开发者能够快速创建游戏。 2. Cocos Creator有哪些基本的组件?Cocos Creator的基本组件包括Sprite、Label、Button、ScrollView、Layout、ProgressBar等。 3. Cocos Creator中的场景是什么?场景是Cocos Creator中最基本的组织单位,每个场景都是一个独立的游戏场景,包含了游戏中所有的元素。 4. Cocos Creator中的节点是什么?节点是Cocos Creator中的最基本的组成单位,它可以包含其他节点或组件,并且可以进行层级关系的管理。 5. Cocos Creator中如何实现动画?Cocos Creator提供了Animation组件,可以通过在编辑器中制作动画来实现。 6. Cocos Creator中如何实现物理引擎?Cocos Creator提供了Physics组件,可以通过添加组件并设置相关参数来实现物理引擎效果。 7. Cocos Creator中如何实现碰撞检测?Cocos Creator提供了Collision组件,可以通过添加组件并设置相关参数来实现碰撞检测。 8. Cocos Creator中如何实现网络通信?Cocos Creator提供了WebSocket和HTTP请求等API,可以通过调用这些API来实现网络通信。 9. Cocos Creator中如何实现音效和音乐?Cocos Creator提供了Audio组件,可以通过添加组件并设置相关参数来实现音效和音乐。 10. Cocos Creator中如何优化游戏性能?可以通过减少节点数量、合并纹理、使用对象池等方式来优化游戏性能。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值