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

p5js开发扫雷点击0周边雷方块或炸弹报Max call stack size exceeded错误

问题核心原因

  1. 无限递归导致栈溢出:reveal方法递归展开相邻方块时,没有判断当前方块是否已经被展开过,相邻的无炸弹方块会互相触发reveal调用,最终触发栈溢出导致游戏崩溃,这也是点击炸弹、点击0炸弹方块都会崩溃的核心诱因。
  2. 炸弹生成逻辑错误:setFeild方法中生成方块的逻辑完全颠倒:调用SelectBomb判断为炸弹后,你重新实例化了一个默认isBomb=true的新方块,相当于所有方块最终都会被标记为炸弹,逻辑完全错误。
  3. 数组越界风险:你定义的grid和baseGrid都是11行,但画布大小只有400400(对应1010的40px方块),第11行的方块超出画布边界,计数周边炸弹时可能触发异常。
  4. 剩余方块计数错误:只有点击方块时会扣减remainingSpaces,自动展开的方块没有扣减,同时递归调用reveal时会重复扣减计数,导致获胜逻辑异常。
  5. 数字被覆盖:没有统一的渲染逻辑,后展开的方块绘制背景时会覆盖相邻方块已经绘制的数字,导致数字消失。

修复方案

  • 给Block类新增isRevealed属性,默认值为false,每次调用reveal时先判断如果已经是true就直接返回,终止递归。
  • 修正炸弹生成逻辑:调用SelectBomb后如果是炸弹就直接保留,不要重新实例化方块。
  • 删掉grid和baseGrid的第11行,保留10行即可,对应400px高度的画布。
  • 只有第一次展开方块的时候扣减remainingSpaces,自动展开的方块同步扣减。
  • 统一先完成所有方块状态更新,再统一绘制所有方块和数字,避免覆盖。

关键代码修改示例

  1. Block构造函数新增属性:
constructor(x, y, scale, color) {
  this.x = x;
  this.y = y;
  this.scale = scale;
  this.color = color;
  this.isBomb = true;
  this.nearBombs = 0;
  this.hasCounted = false;
  this.isRevealed = false; // 新增展开状态标记
}
  1. reveal方法开头加终止条件,统一处理计数:
reveal(placement) {
  if (this.isRevealed) return; // 已经展开过直接返回,终止递归
  this.isRevealed = true;
  remainingSpaces--; // 统一在这里扣减剩余方块数
  // 原有逻辑保持不变
}
  1. 修正setFeild里的炸弹生成逻辑:
let block = new Block(x * 40, y * 40, 40, grid[y][x] == 1 ? "green" : "lime");
block.SelectBomb();
if (block.isBomb) {
  amountOfBombs += 1;
}
grid[y][x] = block;
block.draw();
  1. 删掉mousePressed方法里的remainingSpaces--代码,改为在reveal里统一处理即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 20:57:04