javascript - 向单元格添加点击功能(生命游戏)
问题描述
我也想在我的网格中添加一个 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) {
});
}
解决方案
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>
推荐阅读
- c# - 如何检查字符串数组中每个元素结尾的回车,如果不存在则添加?
- android-recyclerview - 如何使 RecycleView 项目(Xamarin.Android)的两个视图可点击?
- java - 关于 ZGC 和 G1 的 java 垃圾收集
- javascript - 无法在 addEventListener 中调用函数
- javascript - 查找并验证二维矩阵的给定源节点的直接邻居?
- angular - 我应该在哪里使用 Angular 中的安全导航(猫王运算符,“?”)?
- elasticsearch - 如何在 ElasticSearch 中查询可以是整数值的关键字嵌套字段?
- kubernetes - 容器启动失败 - 在 Kubernetes 中使用 Helm Charts 部署 Artifactory
- javascript - @types/draft-js 类型定义掩盖了 immutable-js 的类型定义
- javascript - Ag-grid 在全屏上以 PRINT 格式不响应