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,但是沒有方法掛載上去,點擊的時候也會報這個錯誤。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章