Как создать доску тральщика в javascript?

Я использую элементы div для создания доски тральщика (8 x 8 или что-то еще). Я использовал 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';
    }
}

Все хорошо отображается, но я не могу понять, как отслеживать положение каждой плитки (div), как в системе координат (x, y), поэтому позже я могу выполнять логику игры на основе этих координат. Итак, как я могу отобразить эту сетку?


person Edgar    schedule 23.02.2018    source источник
comment
дать им атрибуты данных elem.setAttribute('data-x', j); elem.setAttribute('data-y', i)   -  person epascarello    schedule 23.02.2018
comment
Хотя этот вопрос выходит за рамки этого вопроса, в учебнике введение в react.js создается тик игра-нолики в React.js. Если вы не боитесь углубиться в более продвинутые подходы, может быть интересным проектом по изменению код для этого примера во что-то, соответствующее вашей идее тральщика. Во всяком случае, вы можете увидеть там, как они представляют доску 3x3, нумеруя последовательно от 0 до 8.   -  person avigil    schedule 23.02.2018


Ответы (6)


Вы можете использовать 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>

person xavvvier    schedule 23.02.2018

Я сделал подобное для проекта, и я использовал атрибуты данных для хранения «координат» и обращался бы к атрибуту данных всякий раз, когда мне нужны координаты. Вот моя функция.

Создает div на основе maxRow и 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);
    }
  }  
}
person JakeofSpades    schedule 23.02.2018
comment
Причина, по которой я сделал это, заключалась в том, чтобы иметь в наличии как число (это был идентификатор для div), так и координаты (x, y) для каждого div, чтобы я мог использовать их по мере необходимости в моем приложении. - person JakeofSpades; 23.02.2018

Yo может хранить положение каждого элемента <div> (координаты x и y) как атрибуты «данных».

Пример:

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.

person pcasme    schedule 23.02.2018

Создавая элементы, давайте каждому уникальное имя. Например elem.id = 'row' + i + 'col' + j;

Позже вы можете использовать document.getElementById( ... )

person Robert Levy    schedule 23.02.2018
comment
Я пробовал что-то подобное, но это довольно сложно, потому что id = 'row' + i + 'col' + j будет строкой, и если я хочу двигаться прямо по строке, я не могу просто увеличить номер строки на 1, потому что id строка. - person Edgar; 23.02.2018
comment
истинный. Ответ @xavvier с использованием атрибутов данных лучше :) - person Robert Levy; 23.02.2018

Вы можете использовать его координаты (x:y) в качестве идентификатора каждого блока.
Вы также можете записать его с помощью одного цикла.

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>

person Rod Ferreira    schedule 23.02.2018

Недавно я весело провел время, создавая это, поэтому я хотел поделиться. Я использовал 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. Другие модули (компоненты) можно найти по ссылке ниже.

https://github.com/bgwest/websweeper

person Benjamin West    schedule 19.06.2018