You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Phaser 3俄罗斯方块克隆:满行消除时游戏崩溃问题求助

问题分析与修复方案

核心错误原因

游戏冻结并抛出Cannot read properties of null (reading 'destroy')的直接原因是**clearRow方法的while循环没有递增索引变量**,导致无限循环:

  1. 第一次循环时,销毁row[0]并将其设为null
  2. 由于没有递增this.i,循环会重复处理row[0],此时row[0]已经是null,调用destroy()就会触发报错
  3. 无限循环直接阻塞游戏主线程,引发冻结现象

除此之外,代码还存在多处逻辑错误,以下是具体修复步骤:


具体修复步骤

1. 修复clearRow方法

添加索引递增逻辑,增加空值判断避免潜在报错,同时改用局部变量避免类属性污染:

clearRow(row){
    let i = 0;
    while(i < row.length){
        // 先判断元素是否存在,再调用destroy
        if(row[i]){
            row[i].destroy();
        }
        row[i] = null;
        i++; // 关键:递增索引,终止循环
    }
}

2. 修复moveDown方法

修正数组length的调用方式(数组的length是属性而非方法),同时修复行下移的逻辑错误:

moveDown(bottomRow, topRow){
    let i = 0;
    const rowHeight = 64; // 定义行高常量,方便后续维护
    while(i < bottomRow.length){
        if(topRow[i]){
            // 移动精灵到下一行的位置
            topRow[i].y += rowHeight;
            // 将精灵引用从上方行转移到下方行
            bottomRow[i] = topRow[i];
            topRow[i] = null;
        }
        i++;
    }
}

3. 优化isFull方法

改用局部变量避免状态污染,同时提前终止循环提升效率:

isFull(row){
    for(let i = 0; i < row.length; i++){
        // 发现空元素立即返回false,无需遍历全部元素
        if(row[i] === null){
            return false;
        }
    }
    return true;
}

4. 简化行填充逻辑(可选)

替换大量else if为坐标计算式,精简代码:

if (this.activeBlock.y === 672){
    // 通过坐标计算列索引:每个方块宽度64,起始x坐标为352
    const colIndex = (this.activeBlock.x - 352) / 64;
    // 确保索引在合法范围内
    if(colIndex >= 0 && colIndex < this.row1.length){
        this.row1[colIndex] = this.activeBlock;
        // 重置活动方块(需补充新方块的生成逻辑)
        this.activeBlock = null;
    }
}

额外优化建议

  • 将11行独立数组改为二维数组(如this.rows = Array.from({length:11}, ()=>Array(10).fill(null))),可大幅简化后续行操作的代码量
  • 填充行后及时重置activeBlock并生成新方块,避免同一方块被重复赋值到数组中

内容的提问来源于stack exchange,提问作者EmptyStone

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.11 20:31:10