cocos新手遇到一个诡异的问题

在跟学一个坦克大战的游戏开发,在修改地图数据的二维数组的时候,打印整个二维数组是好的,但是取某一行的数据的时候永远是undefined
代码如下,求教
genBaseBlock() {

    const baseBlock = instantiate(this.basePrefab);

    baseBlock.parent = this.blockBehind;

    const parentNodeBox = this.blockBehind.getComponent(UITransform).getBoundingBox();

    console.log(this.blocks);

    console.log(this.blocks[0]);

    // baseBlock.setPosition((parentNodeBox.x + parentNodeBox.xMax) / 2, parentNodeBox.y + BASE_SIZE.y / 2);

    baseBlock.setPosition(0, -(MAP_SIZE.height * BLOCK_SIZE.height) / 2 + BASE_SIZE.height / 2);

    BASE_POS.forEach(pos =>{

        this.blocks[pos.x][pos.y] = {type: BlockType.Base, block: baseBlock}

    })

}

打印图

把第二个log放BASE_POS.forEach后试试

就算放在里面报的错,我才尝试直接拿出来打印看看 :sweat_smile:

断点调试一下

BASE_POS.forEach(pos =>{

    this.blocks[pos.x][pos.y] = {type: BlockType.Base, block: baseBlock}

})

这段代码注释掉试试

console.log(this.blocks[0]); 改成console.table(this.blocks[0]);

我的问题没描述清楚 实际情况是BASE_POS 是基地的4个方块,视频是把this.blocks对应坐标的四个方块的对象设置为基地,方便后面的判断。不过运行的时候一直报错 this.blocks[pos.x] 里面的pos.x 合法值是0-23 但是一直报this.blocks[pos.x]是undefined,我就自己尝试在外面把 this.blocks this.blocks[0] 都打印了出来,没想到 this.blocks是好的,this.blocks[0]就是undefined了

你把 console.log(this.blocks); 改为 console.log(JSON.stringify(this.blocks)); 试试,看看打印出什么

我把blocks有关的代码贴一下 里面有成功赋值的,现在我是把赋值的动作都放里面,这样就没有问题
public blocks: BlockData[][] = [];
loadMap(): void{

    resources.load(MAP_RES_PATH + 'map' + myGame.level, TextAsset, (err, data: TextAsset)=>{

        if (err) {

            console.error(err);

            return ;

        }

        const originPos = this.node.getComponent(UITransform).getBoundingBox();

        const text = data.text;

        const textWithLines = text.replace(/[\r\n]+/g, '');

        let index = 0;

        //基地方块信息

        const baseBlock = instantiate(this.basePrefab);

        baseBlock.parent = this.blockBehind;

        const parentNodeBox = this.blockBehind.getComponent(UITransform).getBoundingBox();

        // baseBlock.setPosition((parentNodeBox.x + parentNodeBox.xMax) / 2, parentNodeBox.y + BASE_SIZE.y / 2);

        baseBlock.setPosition(0, -(MAP_SIZE.height * BLOCK_SIZE.height) / 2 + BASE_SIZE.height / 2);

        for (let i=0; i<MAP_SIZE.height; i++) {

            this.blocks[i] = [];

        }

        for (let i=0; i<MAP_SIZE.height; i++) {

            this.blocks[i].length = MAP_SIZE.width;

            for(let j=0; j<MAP_SIZE.width; j++) {

                const blockType = Number(textWithLines[index++]);

                // 预留基地位置

                if (BASE_POS.some(item => item.x === j && item.y === i)) {

                    this.blocks[j][i] = {type: BlockType.Base, block: baseBlock};

                    continue ;

                }

                let node: Node = null;

                switch (blockType) {

                    case BlockType.None:

                        break;

                    case BlockType.Forest:

                        node = instantiate(this.forestPrefab);

                        break;

                    case BlockType.Ice:

                        node = instantiate(this.icePrefab);

                        break;

                    case BlockType.Wall:

                        node = instantiate(this.wallHalfPrefab);

                        break;

                    case BlockType.Water:

                        node = instantiate(this.waterPrefab);

                        break;

                    case BlockType.Swall:

                        node = instantiate(this.swallPrefab);

                        break;

                    default:

                        break;  

                }

                if (node) {

                    node.parent = blockType==BlockType.Forest ? this.blockFront : this.blockBehind;

                    node.setPosition(originPos.x + BLOCK_SIZE.width / 2 + BLOCK_SIZE.width * j, originPos.y + BLOCK_SIZE.height * MAP_SIZE.height - BLOCK_SIZE.height / 2 - BLOCK_SIZE.height * i);

                }

                if (j==11 && i==10) {

                      console.log('地图正在初始化' + node);

                }

                this.blocks[j][i] = {type: blockType, block: node}

                // console.log(this.blocks[j][i]);

            }

        }

        console.log('地图初始化完成' );

        // for (let i=0; i<12; i++) {

        //     for (let j=0; j<12; j++) {

        //         console.log("坐标  " + i + "|" + j + ':' + this.blocks[i][j])

        //     }

        // }

    })

    // this.blocks[0][0] = null;

    // this.genBaseBlock();

}

打印了一个空数组

那不就是了,数组是引用类型,你一开始在面板看到的打印数据是动态的(通过 JSON.stringify 改为打印字符串才是静态的)。

说明那个时候数组就是空的。

感觉懂了一点点,不过这个blocks其他地方都在用,比如子弹和坦克的碰撞,都是能正常拿到对应数据的,怎么这里this.blocks就空了呢

你初始化不对呗,你如果 this.blocks 初始化为 [], 而不是 [[], [], [], ..., []],那肯定出错

console.log打印数组,并不是按代码顺序log出来的,改用table才是按照你写的顺序执行

我主要的问题也不是log 主要在我的理解是blockss是二维数组 blocks[i][j] 只要i是合法值应该就不是undefined。如果是我定义或者初始化的问题导致这个对象不是一个二维数组,那按道理是整个程序的类似调用都应该报同样的错误。而现在的情况的有些地方报,有些地方又不报 :rofl:

你的ij循环为什么里面使用的是blocks[j][i],不会报错吗?
建议你可以多使用devtools断点调试你的代码,会比console输出好一点

新手优先要知道一个重点, console输出日志的对像是引用的, 你输出的数据不是输出那刻的状态而是当刻的状态, 所以真要用console输出最好是使用JSON.stringify

好的 这个点我倒记住了

按你的说法,那我的疑惑是其他地方如果用类似调用应该也是报同样的错误,但下面另外一个类的类似调用并没有保持,功能也是好的

你自己的代码你自己严谨调试,别的地方没报错那就说明执行到那块的时候,这个 blocks 已经被正确初始化/赋值过了,至于是在哪里被初始化了,你的代码肯定你自己去查。

你这个问题我觉得可以终结了,没必要继续问了,后面靠你自己去排查了:joy: