Phaser 3俄罗斯方块克隆:满行消除时游戏崩溃问题求助
问题分析与修复方案
核心错误原因
游戏冻结并抛出Cannot read properties of null (reading 'destroy')的直接原因是**clearRow方法的while循环没有递增索引变量**,导致无限循环:
- 第一次循环时,销毁
row[0]并将其设为null - 由于没有递增
this.i,循环会重复处理row[0],此时row[0]已经是null,调用destroy()就会触发报错 - 无限循环直接阻塞游戏主线程,引发冻结现象
除此之外,代码还存在多处逻辑错误,以下是具体修复步骤:
具体修复步骤
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
相关产品推荐
相关产品推荐

