简体   繁体   English

如何在JavaScript中创建扫雷板?

[英]How to create a minesweeper board in javascript?

I am using div elements to create minesweeper board (8 x 8 or whatever). 我正在使用div元素创建扫雷板(8 x 8或其他)。 I used 2 for loops to create the board of divs 我使用了2个for循环来创建div板

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';
    }
}

Everything is nicely displayed but i can't figure out how to track the position of every tile (div), like a (x,y) coordinate system, so later i can do the game logic based on these coordinates. 一切都很好地显示,但是我不知道如何跟踪每个图块(div)的位置,就像(x,y)坐标系一样,因此以后我可以根据这些坐标来做游戏逻辑。 So how can i map this grid system? 那么我该如何映射这个网格系统呢?

I have done similar for a project and I used data-attributes to hold the "coordinates" and would refer to the data-attribute whenever I needed the coords. 我为一个项目做了类似的工作,并且我使用数据属性来保存“坐标”,并且在需要坐标时会引用数据属性。 Here is my function. 这是我的功能。

Creates the divs based on maxRow and maxColumn 根据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);
    }
  }  
}

You can use Element.setAttribute MDN to add custom attributes to your elements: 您可以使用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> 

Yo can store the position of every <div> element (x and y coordinates) as 'data' attributes. Yo可以将每个<div>元素(x和y坐标)的位置存储为“数据”属性。

Example: 例:

elem.setAttribute('data-x', i);
elem.setAttribute('data-y', j);

You could use getAttribute() later to read the value of the data attributes. 您可以稍后使用getAttribute()来读取数据属性的值。

Example: 例:

var x = elem.getAttribute('data-x');
var y = elem.getAttribute('data-y');

Or even in an easier way: 甚至以更简单的方式:

var x = elem.dataset.x;
var y = elem.dataset.y;

See Using data attributes from MDN for more details. 有关更多详细信息,请参见使用 MDN中的数据属性

As you create elements, give each one a unique name. 创建元素时,为每个元素赋予唯一的名称。 For example elem.id = 'row' + i + 'col' + j; 例如elem.id = 'row' + i + 'col' + j;

You can then later use document.getElementById( ... ) 然后,您可以稍后使用document.getElementById( ... )

You can use it's coordinates (x:y) as the id of each block. 您可以将其坐标(x:y)用作每个块的ID。
You can also write it with a single loop. 您也可以用一个循环编写它。

 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> 

I recently had fun creating this so I wanted to share. 我最近在创建这个游戏时很开心,所以我想分享。 I used SVG because they are flexible and easy to generate. 我之所以使用SVG,是因为它们灵活且易于生成。

These are the BaseBoard loops: 这些是BaseBoard循环:

https://bgwest.github.io/websweeper/ 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 https://github.com/bgwest/websweeper/blob/master/components/MakeBaseBoard.js

The bombs and numbers are then placed in SetBoard.js. 然后将炸弹和数字放置在SetBoard.js中。 The other modules (components) can be found in the link below. 其他模块(组件)可以在下面的链接中找到。

https://github.com/bgwest/websweeper https://github.com/bgwest/websweeper

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM