Cocos 开发中遇到的坑

1、对象为空带来的问题

对象使用前要判断空,网页遇到空对象的执行,可能可以忽略错误继续执行下去,但编译成 Android 后,空必奔,所以前期开发要养成判空的好习惯,不够后面改起来就呵呵了。

2、代码执行快于渲染带来的问题

在 onLoad、onEnable 和 start 方法里用代码方式生成节点时,如果该节点要使用其他节点的参数辅助生成时可能会出问题,因为这两个方法执行时,节点并没有渲染出来,一些基于屏幕的属性没有最终确定(比如基于世界节点的 position),这时候代码生成的节点基于这些属性去设置,就会出现问题,解决的方法是延迟一帧去做操作。这种情况也适用于,如果要对用代码添加的节点做类似于 position 这样的动画时,也会报找不到 _axxxx 的错误。

this.scheduleOnce(() => { // 回调 } )

调度一个只运行一次的回调函数,可以指定 0 让回调函数在下一帧立即执行或者在一定的延时之后执行:

/**
!#en Schedules a callback function that runs only once, with a delay of 0 or larger.
!#zh 调度一个只运行一次的回调函数,可以指定 0 让回调函数在下一帧立即执行或者在一定的延时之后执行。
@param callback A function wrapped as a selector
@param delay The amount of time that the first tick will wait before execution. Unit: s
*/
scheduleOnce(callback: Function, delay?: number): void;	

然后要记住一点,如果一个行为是异步的,那么,这个方法要作用于异步回调之后,操作相应属性时,千万不能贪方便,直接加在行为上。之前就遇到过加在一个异步行为上,然后调起其他 app 页面,然后异步在没有回来之前回调了,这时还没有渲染,位置属性是没有的,回到 Cocos 页才开始渲染,然后位置不是预想的结果,最后搞了好久才发现这个问题。

scheduleOnce 算是神器来着,如果在跳到其它 app 后回来时要做某些事情,然后跳回来没有回调,这种情况,可以在离开本 app 前,scheduleOnce 一个任务,需要的话可以加一下延迟,然后,跳转后只要重新打开本 app,都会调用 scheduleOnce 指定的任务。

3、判断一个字符串是否包含特定字符串
// 该方式在某些手机系统会报错
xxxString.includes('xxx')
// 采用该方式替代上面的方式
xxxString.indexOf('xxx') >= 0
4、异步加载资源造成的父节点挂载错误问题

加载一个预制资源,在加载还没有完成时,就跳到了其他 Scene,这时预制资源加载完成回调,在预制资源中设置 parent 时,如果采用如下方式设置,那么,这时的 parent 就不是原先预想的,而是刚打开的 Scene:

this.node.parent = cc.director.getScene();

parent 不是预想的,那么,如果在预制资源中通过下面的方式去获取目标节点,就会报错:

let targetNode = cc.find('Canvas/nodeParent/targetNode');
let nodeParent = targetNode.parent;
5、getComponent: Type must be non-nil

项目编译部署后,在相应 Scene 中,界面只有初始化的 UI,各种数据加载和交互都无效,不管点击哪个节点(该节点有点击的交互逻辑)都会报这个错误,也不指明报错位置,找了很久都没找出来,而且在 CocosCreater 中通过浏览器 debug 不会报错。只能形而上一回,把之前写的代码重新写一遍,还是一直解决不了,最后只能从 getComponent 入手,新写的代码中只用到一处 getComponent :

    onClickBtn() {
        this.share(() => {
            this.tipNode.getComponent('haha').share(
                () => {
                    this.close();
                }
            );
        });
    },

    share(callBack) {
        ... ...
            utils.bind(() => {
                utils.userInfo(() => {
                    callBack && callBack();
                })
            }, () => {
                this.close();
            });
        ... ...
    },

节点一定是挂载了,那就猜测是 this 作用域问题,毕竟这货经常惹事,一改,呵呵,果然是:

    onClickBtn() {
        let that = this;
        this.share(() => {
            that.tipNode.getComponent('haha').share(
                () => {
                    that.close();
                }
            );
        });
    },

以后遇到要把回调函数传入另一个 js 的情况,一定要用 let that = this; 代替 this 的直接引用 !!!

然后,又遇到会有这个问题的另一种情况:如果一个 node 挂载了 Button,并且 Click Event 改成大于0,但是没有方法挂载上去,点击的时候也会报这个错误。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值