如何在 javascript 中创建扫雷板?
How to create a minesweeper board in javascript?
我正在使用 div 元素来创建扫雷板(8 x 8 或其他)。我使用 2 个 for 循环来创建 divs
的棋盘
window.onload = function () {
var container = document.getElementById('container');
for (var i = 0; i < 8; i++) {
for (var j = 0; j < 8; j++) {
var elem = document.createElement('div');
container.appendChild(elem);
elem.className = 'myclass';
}
var breaker = document.createElement('div');
container.appendChild(breaker);
breaker.className = 'clear';
}
}
一切都很好地显示,但我不知道如何跟踪每个图块的位置 (div),例如 (x,y) 坐标系,所以稍后我可以做游戏逻辑基于这些坐标。
那么我该如何映射这个网格系统呢?
在创建元素时,为每个元素指定一个唯一的名称。例如elem.id = 'row' + i + 'col' + j;
您稍后可以使用 document.getElementById( ... )
我已经为一个项目做了类似的事情,我用 data-attributes 来保存 "coordinates" 并且在我需要坐标时会参考 data-attribute 。这是我的功能。
根据 maxRow 和 maxColumn 创建 div
function createDivs(maxRow) {
var wrapperDiv = document.getElementById("mazeWrapper");
var rowDiv;
for (var i=0; i < maxRow; i++) {
var thisDiv = document.createElement("div");
thisDiv.id = "mazeRow-" + i;
thisDiv.className = "row";
wrapperDiv.appendChild(thisDiv);
for (var j=0; j < maxColumn; j++) {
rowDiv = document.getElementById("mazeRow-" + i);
var thisColumnDiv = document.createElement("div");
thisColumnDiv.id = (i*maxRow)+j;
thisColumnDiv.className = "mazehole";
rowDiv.appendChild(thisColumnDiv);
//Adding in a html data-set to hold X,Y values for coordinate system
var elemID = (thisColumnDiv.id).toString();
var elem = document.getElementById(elemID);
var att = document.createAttribute("data-coords");
att.value = j+","+i;
elem.setAttributeNode(att);
}
}
}
您可以使用 Element.setAttribute
MDN 向您的元素添加自定义属性:
window.onload = function() {
var container = document.getElementById('container');
for (var i = 0; i < 8; i++) {
for (var j = 0; j < 8; j++) {
var elem = document.createElement('div');
container.appendChild(elem);
elem.className = 'myclass';
elem.setAttribute('data-row', i);
elem.setAttribute('data-col', j);
}
var breaker = document.createElement('div');
container.appendChild(breaker);
breaker.className = 'clear';
}
}
.myclass{
width: 20px;
height: 20px;
display: block;
float: left;
border: 1px solid red;
}
.clear{
clear: left;
}
<html>
<body>
<div id="container">
</div>
</body>
</html>
你可以将每个 <div>
元素的位置(x 和 y 坐标)存储为 'data' 属性。
示例:
elem.setAttribute('data-x', i);
elem.setAttribute('data-y', j);
稍后您可以使用 getAttribute() 来读取数据属性的值。
示例:
var x = elem.getAttribute('data-x');
var y = elem.getAttribute('data-y');
或者更简单的方法:
var x = elem.dataset.x;
var y = elem.dataset.y;
有关详细信息,请参阅来自 MDN 的 Using data attributes。
您可以使用它的坐标 (x:y) 作为每个块的 ID。
你也可以用一个循环来写它。
function blockClick(event){
const selected = document.querySelector('#board .block.selected');
if(selected != null){
selected.classList.remove('selected');
}
document.querySelector('#coords').innerHTML = this.id;
this.classList.add('selected');
}
function createBoard(cols, rows, blockSize){
this._boardDom = document.getElementById('board');
const noBlocks = cols * rows;
for(let i = 0; i < noBlocks; i++){
const block = document.createElement('div');
const y = Math.ceil((i + 1)/rows);
const x = (i + 1) - ((y - 1)*rows);
block.id = `${x}:${y}`
// block.innerHTML = `${x}:${y}`; // uncomment this to render x:y
block.style.width = `${blockSize}px`;
block.style.height = `${blockSize}px`;
block.classList.add('block');
block.addEventListener('click', blockClick);
this._boardDom.appendChild(block);
}
this._boardDom.style.width = `${(blockSize*cols) + 2*(rows)}px`
}
createBoard(8,8,30)
#board{
background-color: #eee;
display: flex;
flex-flow: row wrap;
}
#board .block{
border: solid gray 1px;
}
#board .block.selected{
border: solid gray 1px;
background-color: red;
}
<div>
Click on an element to see its coordinates
</div>
<div id="coords">
</div>
<div id="board"></div>
我最近制作这个很开心所以我想分享。我使用 SVG 是因为它们灵活且易于生成。
这些是 BaseBoard 循环:
https://bgwest.github.io/websweeper/
// MakeBaseBoard.js
// named export - genGuiBoard
var genGuiBaseBoard = function(lastRow, lastCol, gameBoardWidth, gameBoardHeight) {
// make base elements and attributes
var boardTiles = document.getElementById("board");
var tile = document.createElementNS("http://www.w3.org/2000/svg", "svg");
var squareElem = document.createElementNS("http://www.w3.org/2000/svg", "rect");
var textElem = document.createElementNS("http://www.w3.org/2000/svg", "text");
// define square with and set loop values to 0
var width = 20;
var height = width;
var row = 0;
var col = 0;
var xcord = 0;
var ycord = 0;
// text element coords
var textXcord = 6;
var textYcord = 15;
// board
tile.setAttribute("width", `${gameBoardWidth}`);
tile.setAttribute("height", `${gameBoardHeight}`);
tile.setAttribute("id", "gameBoard");
boardTiles.appendChild(tile);
// row
for (row = 0; row < lastRow; row++) {
// col
for (col = 0; col < lastCol; col++) {
// rect
var squareElem = document.createElementNS("http://www.w3.org/2000/svg", "rect");
squareElem.setAttribute("class", "game-squares");
squareElem.setAttribute("data-rowIndex", `${row}`)
squareElem.setAttribute("data-colIndex", `${col}`)
squareElem.setAttribute("id", `row${row}col${col}`);
squareElem.setAttribute("width", `${width}px`);
squareElem.setAttribute("height", `${height}px`);
squareElem.setAttribute("x", `${xcord}`);
squareElem.setAttribute("y", `${ycord}`);
squareElem.setAttribute("stroke", "black");
squareElem.setAttribute("stroke-width", "1");
squareElem.setAttribute("stroke-opacity", "0.7");
squareElem.setAttribute("fill", "#b1bcce");
squareElem.setAttribute("fill-opacity", "0.5");
tile.appendChild(squareElem);
// generate text elements with base style but wait to add Bombs
var textElem = document.createElementNS("http://www.w3.org/2000/svg", "text");
textElem.setAttribute("class", `text-squares`);
textElem.setAttribute("data-rowIndex", `${row}`)
textElem.setAttribute("data-colIndex", `${col}`)
textElem.setAttribute("id", `text-id-row${row}col${col}`);
textElem.setAttribute("x", `${textXcord}`);
textElem.setAttribute("y", `${textYcord}`);
textElem.setAttribute("font-size", "1.0em");
// text elements are placed invisibily and event handles are laid later
textElem.setAttribute("fill-opacity", "0.0");
textElem.innerHTML = `#`;
tile.appendChild(textElem);
// looping vars
xcord+=width;
textXcord+=width;
}
// reset x
xcord=0;
textXcord=6;
// continue y
ycord+=width;
textYcord+=width;
}
}
export { genGuiBaseBoard };
https://github.com/bgwest/websweeper/blob/master/components/MakeBaseBoard.js
然后将炸弹和数字放在SetBoard.js中。其他模块(组件)可以在下面的 link 中找到。
我正在使用 div 元素来创建扫雷板(8 x 8 或其他)。我使用 2 个 for 循环来创建 divs
的棋盘window.onload = function () {
var container = document.getElementById('container');
for (var i = 0; i < 8; i++) {
for (var j = 0; j < 8; j++) {
var elem = document.createElement('div');
container.appendChild(elem);
elem.className = 'myclass';
}
var breaker = document.createElement('div');
container.appendChild(breaker);
breaker.className = 'clear';
}
}
一切都很好地显示,但我不知道如何跟踪每个图块的位置 (div),例如 (x,y) 坐标系,所以稍后我可以做游戏逻辑基于这些坐标。 那么我该如何映射这个网格系统呢?
在创建元素时,为每个元素指定一个唯一的名称。例如elem.id = 'row' + i + 'col' + j;
您稍后可以使用 document.getElementById( ... )
我已经为一个项目做了类似的事情,我用 data-attributes 来保存 "coordinates" 并且在我需要坐标时会参考 data-attribute 。这是我的功能。
根据 maxRow 和 maxColumn 创建 div
function createDivs(maxRow) {
var wrapperDiv = document.getElementById("mazeWrapper");
var rowDiv;
for (var i=0; i < maxRow; i++) {
var thisDiv = document.createElement("div");
thisDiv.id = "mazeRow-" + i;
thisDiv.className = "row";
wrapperDiv.appendChild(thisDiv);
for (var j=0; j < maxColumn; j++) {
rowDiv = document.getElementById("mazeRow-" + i);
var thisColumnDiv = document.createElement("div");
thisColumnDiv.id = (i*maxRow)+j;
thisColumnDiv.className = "mazehole";
rowDiv.appendChild(thisColumnDiv);
//Adding in a html data-set to hold X,Y values for coordinate system
var elemID = (thisColumnDiv.id).toString();
var elem = document.getElementById(elemID);
var att = document.createAttribute("data-coords");
att.value = j+","+i;
elem.setAttributeNode(att);
}
}
}
您可以使用 Element.setAttribute
MDN 向您的元素添加自定义属性:
window.onload = function() {
var container = document.getElementById('container');
for (var i = 0; i < 8; i++) {
for (var j = 0; j < 8; j++) {
var elem = document.createElement('div');
container.appendChild(elem);
elem.className = 'myclass';
elem.setAttribute('data-row', i);
elem.setAttribute('data-col', j);
}
var breaker = document.createElement('div');
container.appendChild(breaker);
breaker.className = 'clear';
}
}
.myclass{
width: 20px;
height: 20px;
display: block;
float: left;
border: 1px solid red;
}
.clear{
clear: left;
}
<html>
<body>
<div id="container">
</div>
</body>
</html>
你可以将每个 <div>
元素的位置(x 和 y 坐标)存储为 'data' 属性。
示例:
elem.setAttribute('data-x', i);
elem.setAttribute('data-y', j);
稍后您可以使用 getAttribute() 来读取数据属性的值。
示例:
var x = elem.getAttribute('data-x');
var y = elem.getAttribute('data-y');
或者更简单的方法:
var x = elem.dataset.x;
var y = elem.dataset.y;
有关详细信息,请参阅来自 MDN 的 Using data attributes。
您可以使用它的坐标 (x:y) 作为每个块的 ID。
你也可以用一个循环来写它。
function blockClick(event){
const selected = document.querySelector('#board .block.selected');
if(selected != null){
selected.classList.remove('selected');
}
document.querySelector('#coords').innerHTML = this.id;
this.classList.add('selected');
}
function createBoard(cols, rows, blockSize){
this._boardDom = document.getElementById('board');
const noBlocks = cols * rows;
for(let i = 0; i < noBlocks; i++){
const block = document.createElement('div');
const y = Math.ceil((i + 1)/rows);
const x = (i + 1) - ((y - 1)*rows);
block.id = `${x}:${y}`
// block.innerHTML = `${x}:${y}`; // uncomment this to render x:y
block.style.width = `${blockSize}px`;
block.style.height = `${blockSize}px`;
block.classList.add('block');
block.addEventListener('click', blockClick);
this._boardDom.appendChild(block);
}
this._boardDom.style.width = `${(blockSize*cols) + 2*(rows)}px`
}
createBoard(8,8,30)
#board{
background-color: #eee;
display: flex;
flex-flow: row wrap;
}
#board .block{
border: solid gray 1px;
}
#board .block.selected{
border: solid gray 1px;
background-color: red;
}
<div>
Click on an element to see its coordinates
</div>
<div id="coords">
</div>
<div id="board"></div>
我最近制作这个很开心所以我想分享。我使用 SVG 是因为它们灵活且易于生成。
这些是 BaseBoard 循环:
https://bgwest.github.io/websweeper/
// MakeBaseBoard.js
// named export - genGuiBoard
var genGuiBaseBoard = function(lastRow, lastCol, gameBoardWidth, gameBoardHeight) {
// make base elements and attributes
var boardTiles = document.getElementById("board");
var tile = document.createElementNS("http://www.w3.org/2000/svg", "svg");
var squareElem = document.createElementNS("http://www.w3.org/2000/svg", "rect");
var textElem = document.createElementNS("http://www.w3.org/2000/svg", "text");
// define square with and set loop values to 0
var width = 20;
var height = width;
var row = 0;
var col = 0;
var xcord = 0;
var ycord = 0;
// text element coords
var textXcord = 6;
var textYcord = 15;
// board
tile.setAttribute("width", `${gameBoardWidth}`);
tile.setAttribute("height", `${gameBoardHeight}`);
tile.setAttribute("id", "gameBoard");
boardTiles.appendChild(tile);
// row
for (row = 0; row < lastRow; row++) {
// col
for (col = 0; col < lastCol; col++) {
// rect
var squareElem = document.createElementNS("http://www.w3.org/2000/svg", "rect");
squareElem.setAttribute("class", "game-squares");
squareElem.setAttribute("data-rowIndex", `${row}`)
squareElem.setAttribute("data-colIndex", `${col}`)
squareElem.setAttribute("id", `row${row}col${col}`);
squareElem.setAttribute("width", `${width}px`);
squareElem.setAttribute("height", `${height}px`);
squareElem.setAttribute("x", `${xcord}`);
squareElem.setAttribute("y", `${ycord}`);
squareElem.setAttribute("stroke", "black");
squareElem.setAttribute("stroke-width", "1");
squareElem.setAttribute("stroke-opacity", "0.7");
squareElem.setAttribute("fill", "#b1bcce");
squareElem.setAttribute("fill-opacity", "0.5");
tile.appendChild(squareElem);
// generate text elements with base style but wait to add Bombs
var textElem = document.createElementNS("http://www.w3.org/2000/svg", "text");
textElem.setAttribute("class", `text-squares`);
textElem.setAttribute("data-rowIndex", `${row}`)
textElem.setAttribute("data-colIndex", `${col}`)
textElem.setAttribute("id", `text-id-row${row}col${col}`);
textElem.setAttribute("x", `${textXcord}`);
textElem.setAttribute("y", `${textYcord}`);
textElem.setAttribute("font-size", "1.0em");
// text elements are placed invisibily and event handles are laid later
textElem.setAttribute("fill-opacity", "0.0");
textElem.innerHTML = `#`;
tile.appendChild(textElem);
// looping vars
xcord+=width;
textXcord+=width;
}
// reset x
xcord=0;
textXcord=6;
// continue y
ycord+=width;
textYcord+=width;
}
}
export { genGuiBaseBoard };
https://github.com/bgwest/websweeper/blob/master/components/MakeBaseBoard.js
然后将炸弹和数字放在SetBoard.js中。其他模块(组件)可以在下面的 link 中找到。