Estoy usando elementos div para crear un tablero de buscaminas (8 x 8 o lo que sea). Usé 2 para bucles para crear el tablero de 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';
    }
}

Todo se muestra bien, pero no puedo entender cómo rastrear la posición de cada mosaico (div), como un sistema de coordenadas (x, y), por lo que más tarde puedo hacer la lógica del juego basada en estas coordenadas. Entonces, ¿cómo puedo mapear este sistema de cuadrícula?

2
Edgar 23 feb. 2018 a las 22:31

6 respuestas

La mejor respuesta

Puede usar Element.setAttribute MDN para agregue atributos personalizados a sus elementos:

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>
1
xavvvier 23 feb. 2018 a las 23:54

Puede almacenar la posición de cada elemento <div> (coordenadas x e y) como atributos de 'datos'.

Ejemplo:

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

Puede usar getAttribute () más tarde para leer el valor de los atributos de datos.

Ejemplo:

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

O incluso de una manera más fácil:

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

Consulte Uso de atributos de datos de MDN para obtener más detalles.

1
pcasme 23 feb. 2018 a las 19:54

Recientemente me divertí creando esto, así que quería compartir. Usé SVG porque son flexibles y fáciles de generar.

Estos son los bucles 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

Las bombas y los números se colocan en SetBoard.js. Los otros módulos (componentes) se pueden encontrar en el siguiente enlace.

https://github.com/bgwest/websweeper

0
Benjamin West 19 jun. 2018 a las 14:50

A medida que crea elementos, asigne a cada uno un nombre único. Por ejemplo elem.id = 'row' + i + 'col' + j;

Luego puedes usar document.getElementById( ... )

0
Robert Levy 23 feb. 2018 a las 19:34

Puede usar sus coordenadas (x: y) como la identificación de cada bloque.
También puedes escribirlo con un solo bucle.

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>
0
Rod Ferreira 23 feb. 2018 a las 20:11

He hecho algo similar para un proyecto y usé atributos de datos para mantener las "coordenadas" y me refería al atributo de datos cada vez que necesitaba las coordenadas. Aquí está mi función.

Crea los divs basados en maxRow y maxColumn

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);
    }
  }  
}
1
JakeofSpades 23 feb. 2018 a las 19:36