为生命游戏单元格添加点击事件:实现点击置黑并设值为true
解决生命游戏网格点击切换单元格状态的问题
我来帮你搞定这个问题!你的代码目前有几个需要调整的地方,咱们一步步来修改,实现点击单元格变黑并将其值设为true的功能:
原代码的问题分析
buildGrid里调用choose()但没有接收返回值,导致网格数组全是undefined,没法存储单元格状态- 在
choose()里重复绑定click事件(每个单元格创建时都绑一次),会导致点击一次触发多次回调,性能很差 - 缺少绘制网格的逻辑,没法把单元格状态可视化出来
修改后的完整代码
const canvas = document.querySelector('canvas'); const ctx = canvas.getContext('2d'); canvas.width = 800; canvas.height = 800; const resolution = 20; const horizontalCells = canvas.width / resolution; const verticalCells = canvas.height / resolution; // 初始化网格,所有单元格初始状态为false(未激活,白色) function buildGrid() { return new Array(horizontalCells).fill(null) .map(() => new Array(verticalCells).fill(false)); } // 根据网格状态绘制所有单元格 function drawGrid(grid) { ctx.clearRect(0, 0, canvas.width, canvas.height); for (let x = 0; x < horizontalCells; x++) { for (let y = 0; y < verticalCells; y++) { const cell = grid[x][y]; ctx.fillStyle = cell ? 'black' : 'white'; // 留1px间距让网格更清晰 ctx.fillRect(x * resolution, y * resolution, resolution - 1, resolution - 1); } } } // 初始化网格并绘制初始状态 let grid = buildGrid(); drawGrid(grid); // 给canvas绑定一次点击事件即可 canvas.addEventListener('click', function(event) { // 获取点击位置相对于canvas的坐标(修正页面偏移) const rect = canvas.getBoundingClientRect(); const clickX = event.clientX - rect.left; const clickY = event.clientY - rect.top; // 计算点击对应的网格行列 const cellX = Math.floor(clickX / resolution); const cellY = Math.floor(clickY / resolution); // 确保点击在网格有效范围内 if (cellX >= 0 && cellX < horizontalCells && cellY >= 0 && cellY < verticalCells) { // 将单元格状态设为true(激活状态) grid[cellX][cellY] = true; // 重新绘制网格更新视觉效果 drawGrid(grid); } });
关键部分解释
- 网格初始化:
buildGrid现在生成一个二维数组,所有元素初始为false,代表未激活的白色单元格 - 绘制函数:
drawGrid遍历网格,根据单元格状态设置填充色,绘制每个单元格(resolution - 1是为了留出行列间距,让网格边界更清晰) - 点击事件处理:
- 先计算点击位置相对于canvas的实际坐标,修正页面可能存在的偏移
- 通过除以单元格尺寸
resolution,得到点击对应的网格行列索引 - 修改对应网格位置的值为
true,然后调用drawGrid重新绘制,让单元格视觉上变成黑色
这样就能实现你想要的功能:点击任意单元格,它会变成黑色,同时网格里对应的值被设为true啦!
内容的提问来源于stack exchange,提问作者Dariun
相关产品推荐
相关产品推荐

