JS Canvas实现康威生命游戏:绘制随机方块异常出现线条
康威生命游戏初始细胞绘制错误修复
核心问题分析
你遇到的“随机线条”问题,根源是二维数组的创建与访问方式完全错误:
- 初始化
var cell = [[],[]];只创建了2行空数组,后续循环里的cell[[iHorizontal],[iVertical]] = 0;写法不符合JavaScript二维数组语法,导致所有细胞状态被错误存储在同一行/列,最终绘制时变成线条。 - 随机生成细胞时的
cell[[randomH],[randomV]] = 1;也是同样的错误访问方式,无法正确定位单个细胞位置。
具体修复步骤
- 正确初始化二维数组
在createBoard的外层循环中,先为每一行创建空数组,再填充列的初始值:
let iVertical = 0; cell = []; // 先清空数组 for (; iVertical * cellSize < board.height; iVertical++) { cell[iVertical] = []; // 为当前行创建空数组 let iHorizontal = 0; for (; iHorizontal * cellSize < board.width; iHorizontal++) { cell[iVertical][iHorizontal] = 0; // 正确访问行+列索引 } }
- 修正随机细胞的赋值方式
随机生成细胞时,用cell[行索引][列索引]的格式定位具体细胞:
let i = 0; for (; i < numOfSpawn; i++) { const randomH = Math.floor(Math.random() * Math.floor(board.width / cellSize)); const randomV = Math.floor(Math.random() * Math.floor(board.height / cellSize)); cell[randomV][randomH] = 1; // 行索引在前,列索引在后 }
同时注意用board.width替代board.clientWidth,因为之前已经给board设置了width属性。
- 修正update函数中的细胞状态判断
绘制时正确访问细胞状态,同时增加行存在的判断避免报错:
if (cell[iVertical] && cell[iVertical][iHorizontal] === 1) { context.fillStyle = "white"; context.fillRect( iHorizontal * cellSize, iVertical * cellSize, cellSize, cellSize ); }
修复后的完整代码
let board; let context; const cellAmount = 100; let cellSize; const numOfSpawn = 10; let cell = []; // 初始化空数组,后续动态创建行 function createBoard(){ board.width = document.documentElement.clientWidth; board.height = document.documentElement.clientHeight; cellSize = board.height < board.width ? Math.floor(board.height / cellAmount) : Math.floor(board.width / cellAmount); // 正确创建二维数组 cell = []; let iVertical = 0; for (; iVertical * cellSize < board.height; iVertical++){ cell[iVertical] = []; let iHorizontal = 0; for(; iHorizontal * cellSize < board.width; iHorizontal++){ cell[iVertical][iHorizontal] = 0; } } // 生成随机存活细胞 let i = 0; for (; i < numOfSpawn; i++){ const randomH = Math.floor(Math.random() * Math.floor(board.width / cellSize)); const randomV = Math.floor(Math.random() * Math.floor(board.height / cellSize)); cell[randomV][randomH] = 1; } } function update(){ board.width = document.documentElement.clientWidth; board.height = document.documentElement.clientHeight; cellSize = board.height < board.width ? Math.floor(board.height / cellAmount) : Math.floor(board.width / cellAmount); let iVertical = 0; for (; iVertical * cellSize < board.height; iVertical++){ let iHorizontal = 0; for(; iHorizontal * cellSize < board.width; iHorizontal++){ context.fillStyle = "black"; context.fillRect( iHorizontal * cellSize, iVertical * cellSize, cellSize, cellSize ); // 正确判断细胞状态 if (cell[iVertical] && cell[iVertical][iHorizontal] === 1){ context.fillStyle = "white"; context.fillRect( iHorizontal * cellSize, iVertical * cellSize, cellSize, cellSize ); } } } } window.onload = () => { board = document.getElementById("board"); context = board.getContext("2d"); createBoard(); setInterval(update, 1000/60); };
内容的提问来源于stack exchange,提问作者Marco Gomez
相关产品推荐
相关产品推荐

