精华内容
下载资源
问答
  • CocosCreator 图片资源加载和释放

    千次阅读 2019-06-06 00:17:17
    CocosCreator的官方文档对资源加载和释放方面描述的不算清楚, 不少人对游戏内存的把控没有信心,今天我就来捋一捋CocosCreator资源加载和释放,权当是测试一下各个资源加载和释放的接口 本文基于CocosCreator...

    CocosCreator资源加载和释放

    CocosCreator的官方文档对资源的加载和释放方面描述的不算清楚, 不少人对游戏内存的把控没有信心,今天我就来捋一捋CocosCreator的资源加载和释放,权当是测试一下各个资源加载和释放的接口

    本文基于CocosCreator2.1.1

    0. CocosCreator的resources目录

    使用过CocosCreator的人应该都知道,resorces目录是用来存放那些需要再游戏中动态加载的资源, 官方稳定建议如果资源不需要动态加载,就不要放在该目录下. 经测试, resources目录下的所有资源在构建工程后生成的setting.js文件中有记录,resources目录下的资源越多也就意味着setting.js越大

    1. CocosCreator的各种类型的资源

    在CocosCreator2.1.1版本中,在空场景的情况下cc.loader._cache中一共有20个对象,下文的资源加载和释放的对比将会刨除这20个对象

    (1) cc.Texture2D

    这是一个基本的图片资源类型,很多游戏都有这个

    //加载一个cc.Texture2D类型的资源
    cc.loader.loadRes('pic', cc.Texture2D, (err, data) => {
        if(err) return console.log(err);
        console.log(cc.loader._cache);
    });
    

    以上代码加载完成之后,_cache中多了一个png资源和一个json资源,其中png资源是图片资源是占用内存的大头, 而json资源则代表着一个cc.Texture2D资源对象.
    在cache中,cc.Texture2D对象是以json文件的名字作为key保存的,单独释放_cache中的png对象,内存并没有明显下降,图片占用的内存明显没有被释放掉,而单独释放json的结果是png和json都被释放掉了,内存也有明显的下降,所以加载了那些资源就来,释放时就要完完全全把那些资源释放掉

    • 单独释放png, json文件没有被一起释放,内存也没有明显降低
    cc.loader.release('res/import/8f/8fdd1c3c-1ec9-4018-b57b-551c9b37eba4.png');
    
    • 单独释放json, png和json都被释放了,内存有明显下降
    cc.loader.release('res/import/8f/8fdd1c3c-1ec9-4018-b57b-551c9b37eba4.json');
    

    那么问题来了,怎样知道加载一个cc.Texture2D时还加载了写什么进来呢?
    cc.loader.getDependsRecursively()可以获取传入对象的所有依赖资源,参数类型为cc.Asset,cc.RawAsset,或者string

    cc.Asset: 在 Creator 中,所有继承自 cc.Asset 的类型都统称资源,如 cc.Texture2D, cc.SpriteFrame, cc.AnimationClip, cc.Prefab 等。它们的加载是统一并且自动化的,相互依赖的资源能够被自动预加载(2.0版本文档原文)
    cc.RawAsset: Creator似乎准备把cc.Asset和cc.RawAsset的标准统一起来,在2.0的文档中没有找到cc.RawAsset的说明,应该已经统一了
    string: 这里就是资源的路径

    cc.loader.loadRes('image', cc.Texture2D, (err, data) => {
        //data 就是一个Texture2D对象
        let deps = cc.loader.getDependsRecursively(data);
        console.log(deps);
    });
    
    //deps的输出, 就是加载image时,所加载的所有资源
    ["res/import/8f/8fdd1c3c-1ec9-4018-b57b-551c9b37eba4.png",
    "res/import/8f/8fdd1c3c-1ec9-4018-b57b-551c9b37eba4.json"]
    
    //通过资源的路径也能获取到资源的依赖
    //获取到的是
    //['8fdd1c3c-1ec9-4018-b57b-551c9b37eba4']
    let deps = cc.loader.getDependsRecursively('image');
    //这样也能将加载image时所加载的资源全部释放掉
    cc.loader.release(deps);
    
    (1) cc.SpriteFrame

    SpriteFrame类似于一个中间件,夹在Texture2D和Sprite之间,当我们以cc.SpriteFrame类型进行资源加载时,我们会得到一个SpriteFrame对象,而通过SpriteFrame对象,我们能够获取到3个依赖资源

    cc.loader.loadRes('image', cc.SpriteFrame, (err, data) => {
        //data 就是一个SpriteFrame对象
        let desp = cc.loader.getDependsRecursively(data);
        console.log(desp);
    });
    
    //desp的输出, 就是加载image时,所加载的所有资源
    ["res/import/8f/8fdd1c3c-1ec9-4018-b57b-551c9b37eba4.png",
    "res/import/8f/8fdd1c3c-1ec9-4018-b57b-551c9b37eba4.json",
    res/import/3e/3e24d7c4-3041-4acd-bc91-378df4a24e5f.json]
    

    前两个资源是我们以cc.Texture2D类型进行加载得到的,第三个资源就代表着我们的SpriteFrame对象,这个SpriteFrame对象在_cache中,就是以这个json文件的名字作为key进行保存的

    在释放以Texture2D类型加载进来的资源时, cc.loader.release(‘image’)能够轻松将加载进来的资源释放掉,而想要释放以SpriteFrame类型加载进来的资源,这么简单的处理将会坑到自己
    那是因为从资源路径获取到的依赖资源不包含SpriteFrame, 如果这样鲁莽释放,加载进来的SpriteFrame就残留在了cache中,当我们再次以SpriteFrame类型加载这个资源时,由于cache中残留的SpriteFrame对象,loader将不会加载资源,而是直接返回了cache中这个已经丢失了Texture2D的SpriteFrame,我们此时可以在控制台中看到一大片的webgl的警告

    2. 如何优雅地释放资源

    资源引用计数

    对于释放动态加载的资源,有些人的做法是在加载时获取到加载资源的完整依赖进行累加计数,在释放时对对应资源减一,引用为0时进行真正的释放

    资源份文件夹管理

    另一种做法是把各个界面和场景自己才会用到的资源分文件夹管理,然后通用资源用另一个文件夹管理,在游戏离开某个界面进入另一个界面时,将除通用资源以外的资源统统释放掉

    我个人目前还是跟喜欢后一种做法,一个原因是自己没有一个好的引用计数的实现,另一个原因是经常用到的资源可能会时不时被释放掉,而再次加载有需要一定的时间,会造成不好的体验,就使用了后一种做法

    展开全文
  • 由于受到整体包大小的限制,需要把资源放到服务器上。但是在用cocos creator加载远程服务器资源的时候还是遇到了好多问题,

    相信很多开发微信小游戏的小伙伴都清楚,微信为了用户对小游戏更好的体验,对上传的包体整体大小设置了4mb以下(4mb!  emmm~~~),那么只好把游戏的一些资源放在服务器上了。

    废话不多说,我以cocos creator引擎加载几张放在apache服务器上的图片为例

    ps:我使用的服务器是自己的,另外服务器使用的是centos的操作系统

    在服务器上搭建apache服务器请看centos6.7下搭配apache+php+mysql环境 - CSDN博客

    首先使用xftp软件在服务器上放两张图片资源image1.png、image2.png(注意路径!是你网站站点下!)


    然后在这里建一个php文件(注意路径!是你网站站点下!)


    php文件内容如下:

    <?php
      header('Access-Control-Allow-Origin:*');
      header('Control-type:image/png');
      if(isset($_GET['url'])){
        echo file_get_contents($_GET['url']);
      }
    ?>

    在cocos creator加载资源代码如下:


    现在,很多小伙伴会不解:在服务器上的那个php文件有什么用处呢?

    其实这个php起到了中转的作用,如果你用cocos creator直接加载服务器上的资源的话,会受到浏览器的 CORS 跨域策略限制,所以我们就需要这个php文件了,这个时候我们直接访问这个php文件,并把我们需要的资源路径参数传给它,让这个php帮我们加载资源,然后在它返回的数据添加头信息
    header('Access-Control-Allow-Origin:*');
    header('Control-type:image/png');
    有了这个头信息,浏览器才会允许你加载资源!


    现在我们再说说预加载并设置进度条!

    首先新建节点、挂progressBar组件和新建一个javascript文件!

    最后javaScript示例代码:

    cc.Class({
        extends: cc.Component,
    
        properties: {
            progressBar:{
                default:null,
                type:cc.ProgressBar
            },
    
        },
    
        // LIFE-CYCLE CALLBACKS:
    
        onLoad () {
            this._urls = [
                {url:'http://127.0.0.1(这里填你的服务器ip)/test.php?url=http://127.0.0.1(这里填你的服务器ip)/image1.png', type:'png'},
                {url:'http://127.0.0.1(这里填你的服务器ip)/test.php?url=http://127.0.0.1(这里填你的服务器ip)/image2.png', type:'png'},
                
            ];
    
            this.resource = null;
            this.progressBar.progress = 0;
    
            this._clearAll();
    
            cc.loader.load(this._urls, this._progressCallback.bind(this), this._completeCallback.bind(this));
        },
    
        start () {
    
        },
    
        _clearAll: function() {
            for(var i = 0; i < this._urls.length; ++i) {
                var url = this._urls[i];
                cc.loader.release(url);
            }
        },
    
        _progressCallback: function(completeCount, totalCount, res) {
            //加载进度回调
            console.log('第 ' + completeCount + '加载完成!');
            this.progress = completeCount / totalCount;
            this.resource = res;
            this.completeCount = completeCount;
            this.totalCount = totalCount;
        },
    
        _completeCallback: function(err, texture) {
            //加载完成回调
        },
    
        update (dt) {
            if(!this.resource){
                return ;
            }
            var progress = this.progressBar.progress;
            if(progress >= 1){
                console.log('加载完成')
                //加载完成
                this.progressBar.node.active = false;
                this.enabled = false;
                return ;
            }
    
            if(progress < this.progress){
                progress += dt;
            }
    
            this.progressBar.progress = progress;
    
        },
    });

    不要忘了把New ProgressBar节点拖到脚本里哦!

    来个预览!

    好了,教程到这里就完结了。不足之处,欢迎指出!

    展开全文
  • Cocos Creator加载文本文件

    千次阅读 2019-01-14 21:25:23
    之前用cocos creator加载一些cc.SrpiteFrame的时候,利用cc.loader.loadRes()方法甚是便捷。cc.loader.loadTxt被移除之后,怎么加载文本文件呢? cc.loader.loadRes 我们知道cc在动态加载文件的时候需要将文件放在...

    Cocos Creator 加载文本文件

    写在前面

    之前用cocos creator加载一些cc.SrpiteFrame的时候,利用cc.loader.loadRes()方法甚是便捷。cc.loader.loadTxt被移除之后,怎么加载文本文件呢?

    cc.loader.loadRes

    我们知道cc在动态加载文件的时候需要将文件放在resources文件下。其次我们要搞清楚的一点事,如下代码中的res是什么?

    cc.loader.loadRes(url, function(err, res){
    	if(err){
    		cc.error(err.message);
    		return;
    	}
    	...
    });
    

    下面代码加载了一个SpriteFrame:

    		cc.loader.loadRes("characters/C12", function (err, pic) {
                if (err) {
                    cc.error(err.message);
                    return;
                }
                console.log(pic);               // 由于是图片,这里pic是cc_Texture2D对象
                console.log(pic.toString());    // res/import/97/976d9e70-d09f-48c2-93e5-85cccfb6c69d.jpg
                console.log(pic.nativeUrl);     // res/import/97/976d9e70-d09f-48c2-93e5-85cccfb6c69d.jpg
                // 可以看到 pic.toString()方法返回nativeUrl的值
            });
    

    下面的代码是加载一个文本文件:

    		cc.loader.loadRes("configure/character", function (err, conf) {
                if (err) {
                    cc.error(err.message);
                    return;
                }
                console.log(conf);               // 由于是文本,这里conf是cc_Asset对象
                console.log(conf.toString());    // res/import/14/1400c110-37ad-489f-9016-0637a4a0709f.conf
                console.log(conf.nativeUrl);     // res/import/14/1400c110-37ad-489f-9016-0637a4a0709f.conf
                // 可以看到 conf.toString()方法返回nativeUrl的值
                // console.log("url: " + conf)   // 这里应该会默认调用 toString 方法
    
                /**
                 * 由此可见 loadRes真正返回的是资源对象
                 * 如果是内置的资源类型,那么可以特定对象(如cc.SpriteFrame,cc.Altlas)赋值
                 * 而一些文本文件,则需要进一步通过cc.loader.load()函数进行加载
                 */
                cc.loader.load(conf.nativeUrl, function(err, text){
                    console.log(text);
                });
            });
    

    我们可以看到cc.loader.loadRes函数返回的是一个资源对象,而对于非内置的资源类型,需要进一步加载。这对于文本、图片都是适用的。而cc.loader.load()函数的url参数则需要用到资源对象的nativeUrl属性。

    总结

    非内置资源的加载方式,通过cc.loader.loadRres获取资源对象,在通过cc.loader.load通过资源对象的nativeUrl属性获取资源内容。

    cc.loader.loadRes("configure/character", function(err, conf) {
        if (err) {
            cc.error(err.message);
            return;
        }
        
        cc.loader.load(conf.nativeUrl,
        function(err, text) {
            console.log(text);
        });
    });
    

    这里character是一个文本文件,loadRes不要指定后缀名。

    展开全文
  • CocosCreator 动态加载与远程加载资源汇总 概述 所有需要通过 cc.loader.loadRes 动态加载的资源,都必须放置在 resources 文件夹或它的子文件夹下。如果一份资源仅仅是被 resources 中的其它资源所依赖,而不需要...

    CocosCreator 动态加载与远程加载资源汇总

    概述

    • 所有需要通过 cc.loader.loadRes 动态加载的资源,都必须放置在 resources 文件夹或它的子文件夹下。如果一份资源仅仅是被 resources 中的其它资源所依赖,而不需要直接被 cc.loader.loadRes 调用,那么请不要放在 resources 文件夹里。

    • resources 文件夹里面的资源,可以引用文件夹外部的其它资源,同样也可以被外部场景或资源引用到。项目构建时,除了已在构建发布面板勾选的场景外,resources 文件夹里面的所有资源,连同它们关联依赖的 resources 文件夹外部的资源,都会被导出。

    • 关于 resources 的更多信息,可参考文档:获取和加载资源 - 动态加载 Asset

    动态加载资源

    资源下载

    链接: 百度网盘 提取码: pj6f

    动态加载预制资源

    
    newNode(position, callBack) {
        let newNode = null;
        if (!this.nodePool) {
            this.nodePool = new cc.NodePool();
        }
        if (this.nodePool.size() > 0) {
            newNode = this.nodePool.get();
            this.setNode(newNode, position, callBack);
        } else {
            cc.loader.loadRes("prefab/leftOright", cc.Prefab, function (err, prefab) {
                if (err) {
                    return;
                }
                newNode = cc.instantiate(prefab);
                this.setNode(newNode, position, callBack);
            }.bind(this));
        }
    },
    

    动态加载字体

        setCurrentWater(type, number) {
            let currentWaterLabel = this.targetWaterNode.getChildByName("current").getComponent(cc.Label);
            currentWaterLabel.string = number;
            this.setFont("fonts/Yellowchars", currentWaterLabel);
        },
    
        /**
         * 设置字体
         * @param {*} url
         * @param {*} label 
         */
        setFont(url, label) {
            //动态加载字体
            cc.loader.loadRes(url, cc.Font, function (err, res) {
                if (err) {
                    return;
                }
                label.font = res;
            });
        },
    

    动态加载龙骨资源

    异步动态加载龙骨资源

    //异步加载龙骨动画
    this.runAsyncGetDragonRes("huajipao", this._currentTimeScale)
        .then(function (data) {
            console.log("回调:" + data.timeScale);
            that.armatureDisPlay = data;
        })
        .catch(function (reason) {
            console.log(reason);
        });
    
    
    /**
     * 获取龙骨资源并播放动画
     * @param {*} dragonName 龙骨文件夹名称 
     * @param {*} timeScale 动画缩放率
     */
    runAsyncGetDragonRes(dragonName, timeScale) {
        var p = new Promise(function (resolve, reject) {
            cc.loader.loadResDir('dragon/' + dragonName, function (err, assets) {
                if (err) {
                    return;
                }
                if (assets.length <= 0) {
                    return;
                }
                var newHero = new cc.Node();
                
                this.node.getChildByName("players").addChild(newHero);
                newHero.setPosition(cc.v2(0, 0));
                newHero.setScale(1, 1);
                let armatureDisPlay = newHero.addComponent(dragonBones.ArmatureDisplay);
                for (let i in assets) {
                    if (assets[i] instanceof dragonBones.DragonBonesAsset) {
                        armatureDisPlay.dragonAsset = assets[i];
                    }
                    if (assets[i] instanceof dragonBones.DragonBonesAtlasAsset) {
                        armatureDisPlay.dragonAtlasAsset = assets[i];
                    }
                }
                armatureDisPlay.armatureName = 'Armature';//龙骨支干
                armatureDisPlay.playAnimation('newAnimation');//龙骨动画名称
                armatureDisPlay.timeScale = timeScale;
                resolve(armatureDisPlay);
            }.bind(this));
        }.bind(this));
        return p;
    },
    

    动态加载声音

     cc.loader.loadRes("music/bgm", cc.AudioClip, function (err, clip) {
         if (err) {
             return;
         }
         this._dynamicAudio = clip;
     }.bind(this));
    
    
    playBgmAudio() {
      if (Global.isAudio && this._dynamicAudio && (!this.bgmAudioId || this.getState(this.bgmAudioId) != cc.audioEngine.AudioState.PLAYING)) {
        this.bgmAudioId = cc.audioEngine.play(this._dynamicAudio, true, 1);
      }
    },
        
    getState(id) {
      return cc.audioEngine.getState(id);
    },
    

    远程加载

    远程加载图片

    // 设置图片
    function setImg(imgNode, spriteFrame) {
        imgNode.getComponent(cc.Sprite).spriteFrame = spriteFrame;
    }
    // 加载远程资源
    function loadImgByUrl(imgNode, remoteUrl, imageType) {
        if (!imageType) {
            imageType = "png";
        }
        cc.loader.load({
            url: remoteUrl,
            type: imageType
        }, function (err, texture) {
            if (err) {
                return;
            }
            setImg(imgNode, new cc.SpriteFrame(texture));
        });
    }
    // 用绝对路径加载设备存储内的资源,比如相册
    function loadLocal(imgNode, absolutePath) {
        cc.loader.load(absolutePath, function (err, texture) {
            if (err) {
                return;
            }
            setImg(imgNode, new cc.SpriteFrame(texture));
        });
    }
    
    展开全文
  • cocos creator 动态加载资源 引入文件路径 import resPath from "resPath"; 加载整个文件夹 //动态加载某个文件下的所有资源,并使用 setSpriteFrame(sprite, name) { let texName = resPath[name]; cc.loader....
  • 资源加载封装 import { Asset, AssetManager, dragonBones, ImageAsset, JsonAsset, resources, _decorator } from "cc"; import { LogData } from "../log/LogData"; ... /** 动态加载资源,可以
  • CocosCreator支持像png、jpg、jpge等格式的纹理资源,但也有一些格式的纹理资源不支持。 例如 *.ico 类型的文件,也就是图标类型的资源,编辑器是无法识别的 实际它就是这样的一张纹理资源: 如果我们在加载时...
  • 如要了解 CocosCreator 引擎资源加载与释放的原理,调试、修改引擎代码有助于对其原理进行理解。因此文中会先介绍 CocosCreator 引擎各部分及其文件夹,然后介绍调试、修改引擎源码的方法,最后对其原理进行分析。 ...
  • cocoscreator获取和加载资源.pdf
  • 最近的开发中碰到这样一个问题: 问题描述:cocos creator版本 2.4.3,使用cc.loader.loadRes加载声音文件(mp3),加进内存后内存
  • CocosCreator之动态加载资源 // 预加载资源 cc.resources.preload('test.json'); // 本地加载资源 // "url"为本地resources文件夹下的资源路径 cc.loader.loadRes("url", cc.SpriteFrame, (err, res) => { if ...
  • 所谓的动态加载资源,指的是资源只能在场景中预先设置好,没办法动态切换。如果需要动态切换就需要用到资源的动态加载 动态加载需要注意两点: 1、所有通过脚本动态加载的资源,都必须放在resource文件夹或它的子...
  • 动态加载资源要注意两点,一是所有需要通过脚本动态加载的资源,都必须放置在resources文件夹或它的子文件夹下。resources需要在 assets 文件夹中手工创建,并且必须位于 assets 的根目录 resources文件夹中的...
  • CocosCreator微信小游戏开发系列文章,是我在逐步开发过程中,基于官方文档之上,记录一些重点内容,以及对官方文档中有些知识点的补充和分析。 正文 Cocos Creator导入资源方式: 将资源文件拷贝到项目资源文件夹...
  • 在学习CocosCreator 的时候,动态加载prefab资源 发现当层级管理器下 canvas 与 你加载的图片为同级关系时就会出现宽度不正确的问题 解决方案 ,层级管理器 canvas应该是父级目录,其余子文件应当放置在该文件下,...
  • CocosCreator 动态加载资源

    千次阅读 2019-06-17 18:23:01
    Cocos官方推荐用cc.loader.loadRes()方法。 三个参数: 1.资源地址 不要加上resources目录。资源的后缀格式不要写,...2.第二个参数,用来指定你要加载资源的类型 对于单个图片资源,资源类型为cc.SpriteFrame;...
  • cocoscreator获取和加载资源

    万次阅读 2017-12-03 19:37:06
    资源的分类如何在属性检查器里设置资源动态加载资源加载远程资源和设备资源资源的依赖和释放 资源的分类 目前的资源分成两种,一种叫做Asset,一种叫做Raw Asset。 Asset Creator 提供了名为 "Asset" 的资源类型,cc...
  • cocoscreator资源加载

    2019-09-09 18:56:59
    cc.loader.loadRes:用来加载resource目录下的Asset(资源) 和cc.loader.load不同的是,loadRes每次只能加载一个Asset。调用时只需传入相对resource的路径即可,并且路径结尾处不能包含文件扩展名 ...
  • 加载和切换场景 cc.director.loadScene(‘MyScene’) 场景加载回调 加载场景时,可以附加一个参数用来指定场景加载后的回调函数: cc.director.loadScene(“MyScene”, onSceneLaunched); 上一行里 onSceneLaunched ...
  • 一分钟定制CocosCreator加载页面

    千次阅读 2019-09-19 12:31:49
    我们都知道 CocosCreator 打包 Web 端后会有一个黑黑的加载界面,而很多开发的小伙伴们是不太懂前端的。那么如何通过一篇文章快速学会定制页面呢? 正文 总览 在打包 Web 项目时,我们基本上都会选择手机端,我就拿...
  • 开发版本:cocos creator 2.3.2 加载方法: // prefab为该预制体所在的文件夹名称,该文件夹需要配置为Bundle,否则会找不到 cc.assetManager.loadBundle('prefab', (err: Error, prefab: cc.AssetManager.Bundle) =&...
  • cocos creator 2.1.2 查阅代码目录:[cocos creator 2.1.2项目目录]\resources\engine \cocos2d\core\load-pipeline\uuid-loader.js \cocos2d\core\load-pipeline\binary-loader.js 等等 原因 制作关卡游戏,...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 2,898
精华内容 1,159
关键字:

cocoscreator加载资源