cocos creator日常积累--持续更新

欢迎入群学习交流:535098339
各路大神弄的资料

 // 1.动态加载资源
 //第一个参数是resource下的文件名,不加后缀.function里第二个参数是资源类型

 // 加载 Prefab
 cc.loader.loadRes("test assets/prefab", function (err, prefab) {
     let newNode = cc.instantiate(prefab);
     cc.director.getScene().addChild(newNode);
 });

 // 加载 AnimationClip
 cc.loader.loadRes("test assets/anim", function (err, clip) {
     myNode.getComponent(cc.Animation).addClip(clip, "anim");
     anim.play('anim'); //播放动画
 });

 // 加载 SpriteAtlas(图集),并且获取其中的一个 SpriteFrame
 // 注意 atlas 资源文件(plist)通常会和一个同名的图片文件(png)放在一个目录下, 所以需要在第二个参数指定资源类型
 cc.loader.loadRes("test assets/sheep", cc.SpriteAtlas, function (err, atlas) {
     let frame = atlas.getSpriteFrame('sheep_down_0');
     sprite.spriteFrame = frame;
 });
 // 加载 SpriteFrame
 cc.loader.loadRes("test assets/image", cc.SpriteFrame, function (err, spriteFrame) {
     myNode.getComponent(cc.Sprite).spriteFrame = spriteFrame;
 });
 // 加载 SpriteFrame第二种方式
 //这个方法与上一个方法不同的是直接改图片的纹理,但凡是场景用到的test.png,一定会变成一样的.如果要批量改一个预制体的图片的话建议用上一个
 sprite.spriteFrame.setTexture(cc.url.raw('res/test.png'));
 //9.加载json
 let url = cc.url.raw('resources/HeroDefault.json')
 cc.loader.load(url, function (err, res) {
     cc.log('load[' + url + '], err[' + err + '] result: ' + JSON.stringify(res));
 });
 // http://blog.csdn.net/alpha_xiao/article/details/52102252 这个比官网的详细,有示意图,新手可以看
 // http://sunmoon-x.com/cocoscreator%E8%B5%84%E6%BA%90%E5%8A%A0%E8%BD%BD1-3-1%E7%89%88%E6%9C%AC/ 这个可以更深入的了解加载资源.
//加载播放声音
cc.audioEngine.play(cc.url.raw("resources/sounds/test.mp3" + url), false,1);
//加载网络图片
      setSpriteFrame_sprite_url: function (sprite, url) { //设置网络图片
        //加载https图片失败用下面方法.
       // let url_http=url.replace('https','http')
        cc.loader.load({
            url: url,
            type: 'png'
        }, function (err, texture) {
            if (err) {
                console.log('加载图片失败' + err)
                return;
            }
            sprite.spriteFrame = new cc.SpriteFrame(texture);
            //sprite.spriteFrame.setTexture(texture) 希望你放弃setTexture这种方法,贼坑!
        });
    },

 // 2.顺序执行动作.
 let moveTime = 0.2;
 let x = 0;
 let y = -32;
 let action = cc.moveBy(moveTime, x, y); //向下移动32像素
 let finished = cc.callFunc(function (target, score) {
     cc.log('回调发生')
 }, this, 100)
 let myAction = cc.sequence(action, finished);
 // 3. 官方示例碰撞检测 点击刚体触发事件
 cc.Class({
     extends: cc.Component,
     properties: {
         collider: {
             default: null,
             type: cc.PolygonCollider
         },
         title: {
             default: null,
             type: cc.Label
         }
     },
     // use this for initialization
     onLoad: function () {
         cc.director.getCollisionManager().enabled = true;
         cc.director.getCollisionManager().enabledDebugDraw = true;
         this.title.string = 'normal';
         cc.eventManager.addListener({
             event: cc.EventListener.TOUCH_ONE_BY_ONE,
             onTouchBegan: (touch, event) => {
                 let touchLoc = touch.getLocation();
                 if(cc.Intersection.pointInPolygon(touchLoc,this.collider.world.points)){
                     this.title.string = 'Hit';
                 } else {
                     this.title.string = 'Not hit';
                 }
                 return true;
             },
         }, this.node);
     },
 });
 // 4.自定义类 把类作为一个对象的属性,比如二维数组的实现
 let Item = cc.Class({
     name: 'Item',
     properties: {
         id: 0,
         itemName: '',
         itemPrice: 0,
         iconSF: cc.SpriteFrame
     }
 });
 cc.Class({
     extends: cc.Component,
     properties: {
         items: {
             default: [],
             type: Item
         }
     },
 });
 //5.得到一个节点
 this._player = this.node.getChildByName('player');
 this._player = cc.find('Canvas/player')
 //6.设置颜色
 this.node.color = cc.Color.RED; //默认是WHITE.
 //7.导入外部脚本
 let cfg = 1;
 module.exports = cfg; //这两句是cfg.js 在other.js里获取cfg的值用: let cfg=require('cfg');
 //module.exports 是一个空对象,也可以像下面那样来获得cfg
 module.exports = {
     getCfg: function () {
         return cfg;
     },
 }
 //8.用本地数据库保存设置,游戏存档之类的.
 if (JSON.parse(cc.sys.localStorage.getItem('config')) !== undefined) {
     let config = JSON.parse(cc.sys.localStorage.getItem('config'));
 }
 cc.sys.localStorage.setItem('config', JSON.stringify(config));
 //9.音频默认是使用 webAudio 的方式加载并播放的,只有在不支持的浏览器才会使用 dom 元素加载播放。
 cc.loader.load(cc.url.raw('resources/background.mp3'), callback);
 //10.长按实现人物持续移动
    const self=this;
    this.node.on(cc.Node.EventType.TOUCH_START, function (event) {
        this.cb = function () {
            cc.log("长按")
        };
        self.scheduleOnce(this.cb, 0.15);
    }, this.node);
    this.node.on(cc.Node.EventType.TOUCH_END, function (event) {
        self.unschedule(this.cb);
    }, this.node);
 //11 本地存储图片,用原生
 loadNative = function (url, callback) {
     let dirpath = jsb.fileUtils.getWritablePath() + 'img/';
     let filepath = dirpath + MD5(url) + '.png';

     function loadEnd() {
         cc.loader.load(filepath, function (err, tex) {
             if (err) {
                 cc.error(err);
             } else {
                 let spriteFrame = new cc.SpriteFrame(tex);
                 if (spriteFrame) {
                     spriteFrame.retain();
                     callback(spriteFrame);
                 }
             }
         });

     }

     if (jsb.fileUtils.isFileExist(filepath)) {
         cc.log('Remote is find' + filepath);
         loadEnd();
         return;
     }

     let saveFile = function (data) {
         if (typeof data !== 'undefined') {
             if (!jsb.fileUtils.isDirectoryExist(dirpath)) {
                 jsb.fileUtils.createDirectory(dirpath);
             }

             if (jsb.fileUtils.writeDataToFile(new Uint8Array(data), filepath)) {
                 cc.log('Remote write file succeed.');
                 loadEnd();
             } else {
                 cc.log('Remote write file failed.');
             }
         } else {
             cc.log('Remote download file failed.');
         }
     };

     let xhr = new XMLHttpRequest();

     xhr.onreadystatechange = function () {
         cc.log("xhr.readyState  " + xhr.readyState);
         cc.log("xhr.status  " + xhr.status);
         if (xhr.readyState === 4) {
             if (xhr.status === 200) {
                 xhr.responseType = 'arraybuffer';
                 saveFile(xhr.response);
             } else {
                 saveFile(null);
             }
         }
     }.bind(this);
     xhr.open("GET", url, true);
     xhr.send();
 };
 
 // 设置适配模式
        cc.view.setOrientation(cc.macro.ORIENTATION_PORTRAIT);
        cc.view.setDesignResolutionSize(750, 1334, 0);
//然后场景里的节点加上widget适配.
//后台监听函数
 cc.game.on(cc.game.EVENT_HIDE, function(event){
            cc.log("切换后台",event);
        });
        cc.game.on(cc.game.EVENT_SHOW, function(event){
            cc.log("切换前台",event);
        }); 
//得到java的变量
var id = jsb.reflection.callStaticMethod("org/cocos2dx/javascript/JsbService", "getUidToken", "()Ljava/lang/String;");
var result = jsb.reflection.callStaticMethod("org/cocos2dx/javascript/JsbService", "getBatteryPercent", "()I");
jsb.reflection.callStaticMethod("org/cocos2dx/javascript/JsbService", "wxShareUrl", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;I)V", url, title, desc, type);
//取消node的所有监听
this.node.targetOff(this.node);
//取消计时器的所有监听
this.unscheduleAllCallbacks();

    //--->>> 动作,类似c2dx api 基本无变化
        var mTo = cc.moveBy(1,-100, -200);
        var mAction = cc.repeatForever(cc.sequence(cc.moveBy(1,-100, -200),mTo.reverse(),cc.delayTime(0.5),cc.callFunc(function(action,data){
            console.log("action callback:"+data.himi);
        },this,{tx:100,himi:"i'm action callback and bring data"})));
        mySprite.node.runAction(mAction);
        //暂停动作
        mySprite.node.stopAction(mAction);
//

顺便提一下cocos creator里是通过设置 节点的 active 属性,来控制可见性的,
setPosition等方法只能修改本节点,不能修改附属的子节点,但是可以通过给父节点加动作runAction(cc.MoveTo(...)),来变相达到想要的效果
动作系统:https://blog.csdn.net/likendsl/article/details/53413050

//按钮全局添加音效事件
cc.Component.EventHandler._emitEvents = cc.Component.EventHandler.emitEvents;
cc.Component.EventHandler.emitEvents = function (clickEvents, event) {

    if (event instanceof cc.Event.EventTouch) {
        if (event.type == "touchend") {
            cc.ss.sound.playEffect("buttonclick.mp3")
        }
    }
    cc.Component.EventHandler._emitEvents.apply(this, arguments);
};
//设置场景全局加速
cc.director.getScheduler().setTimeScale(1.5);
cc.director.getPhysicsManager().enabledAccumulator = true;
cc.director.getPhysicsManager().FIXED_TIME_STEP = 1 / 20

某大神关于性能优化的一些见解https://forum.cocos.com/t/topic/75032/2

不清楚你用的版本是否可以使用渲染组件了。
可以的话,鱼如果可以用instance来渲染,理论上可以大幅度地减少drawcall。
骨骼动画的定制我也不太清除引擎组的进度。但是以我最近在写的骨骼动画来说,减少动画K帧的数目,应该可以减少找插值的关键帧的时间,但这个不一定是瓶颈。
有一个很值得注意的地方,不开启碰撞检测的时候,还有30ms,但是加上碰撞检测,达到了几百ms,有理由怀疑瓶颈在 碰撞检测 上,或者说,由于碰撞后逻辑导致的 骨骼动画显示,消失,导致提交的cmdbuffer需要不断重新创建,骨骼动画不断调用构造函数,析构函数的开销
至于解决方案:
前者好说,用上 场景管理树 :hlbvh, quat-tree, 应该都有现成的,感兴趣可以去看看bullet物理引擎的官方文档,里面碰撞检测管线的描述很详细,这可以减少碰撞检测的开销,但是不好说减少多少,毕竟场景也没多少物体。
后者呢,老生常谈,用 对象池 吧。如果开销瓶颈不是动画,而是创建和析构上,那么回收骨骼动画的时候,最好不要将骨骼动画的节点从节点树上拿下来,而是 将骨骼动画移动到屏幕外(移动到场景外,会破坏场景管理树的结构,需要重新创建,所以记得profile一下性能瓶颈,究竟是碰撞是瓶颈,还是渲染是瓶颈,得出结论后,再决定是否要移动骨骼动画到场景外,这是一环套一环的) ,然后可以进行一下尝试:
1.将节点的active设置为false
2.将节点的动画停掉,
3.将节点的透明度设置为0
并且这几个方案都尝试一下吧。哪一个真正能提高性能,我最近也在写游戏引擎,个人愚见,这个和引擎开发者,做出的 设计取舍 有关。最好去问问做这一块的引擎开发者

你可能感兴趣的:(cocos creator日常积累--持续更新)