首页 > 解决方案 > 向单元格添加点击功能(生命游戏)

问题描述

我也想在我的网格中添加一个 eventListener,所以如果我要单击一个单元格,它将变成黑色并获得值为 true。如何将单元格值更改为 true?


const canvas = document.querySelector('canvas');
    const ctx = canvas.getContext('2d');
    canvas.width = 800;
    canvas.height = 800;

    const resolution = 20;
    const horizontal = canvas.width / resolution;
    const vertikal = canvas.height / resolution;

    function buildGrid() {
        return new Array(horizontal).fill(null)
            .map(()=> new Array(vertikal).fill(null)
                .map(function(){choose();})); //Math.floor(Math.random() * 2)
    }


function choose () {
    canvas.addEventListener('click', function (event) {

    });
}

标签: javascriptcanvas

解决方案


First you need to create an array which holds the state of each cell (false/true). A two-dimensional array is the best choice for this use-case.

var grid = new Array();
for (var a = 0; a < vertikal; a++) {
  grid[a] = new Array();
  for (var b = 0; b < horizontal; b++) {
    grid[a].push(false);
  }
}

This creates such an array and prepopulates each element with false.

Each cell's size is controlled by the variable resolution. Inside the callback function for the click event listener you've attached to the canvas, we can figure out which cell we've clicked by using this formula: floor(mousePosition/resolution)

A simple example: We know that each cell is 20 pixels. If the user clicked at x=123, we get 123/20 = 6.15 == 6

The same needs to be done for the vertical mouse click of course.

Now we can simply toggle a cell's state using this:

grid[cellY][cellX] = !grid[cellY][cellX];

So if the value of the element at cellX;cellY has been false it becomes true and vice versa.

Finally we need to loop over the array and update the canvas accordingly.

Here's the full sample. (click on 'Run code snippet' and click anywhere inside the canvas to toggle a cell)

const canvas = document.querySelector('canvas');
const ctx = canvas.getContext('2d');
canvas.width = 800;
canvas.height = 800;

const resolution = 20;
var horizontal = canvas.width / resolution;
var vertikal = canvas.height / resolution;

var grid = new Array();
for (var a = 0; a < vertikal; a++) {
  grid[a] = new Array();
  for (var b = 0; b < horizontal; b++) {
    grid[a].push(false);
  }
}

function updateGrid() {
  ctx.clearRect(0, 0, canvas.width, canvas.height);
  for (var a = 0; a < vertikal; a++) {
    for (var b = 0; b < horizontal; b++) {
      if (grid[a][b]) {
        ctx.fillRect(b * resolution, a * resolution, resolution, resolution);
      }
    }
  }

}
canvas.addEventListener('click', function(event) {
  var cellX = Math.floor((event.clientX - canvas.offsetLeft) / resolution);
  var cellY = Math.floor((event.clientY - canvas.offsetTop) / resolution);
  grid[cellY][cellX] = !grid[cellY][cellX];
  updateGrid();
});
<canvas></canvas>


推荐阅读