Как я могу добавить «скрытую» сетку поверх холста с фоновым рисунком? - PullRequest
2 голосов
/ 22 февраля 2020

Я делаю пошаговую игру html / js и создал элемент canvas, используя javascript. Я поместил повторяющуюся фоновую картинку, чтобы она выглядела как доска 10 × 10 в квадрате, но я хочу поставить сетку поверх нее, чтобы я мог в конечном итоге сделать каждый «квадрат» кликабельным для перемещения персонажей, квадратов, которые будут светиться при наведении и т. Д. c .

Как я могу сделать это самым простым способом?

Спасибо.

Вот код, который я использовал для создания холста в javascript:

var myGameArea = {
    canvas : document.createElement("canvas"),
    start : function() {
        this.canvas.width = 480;
        this.canvas.height = 480;
        this.canvas.style.cursor = "default"; 
        this.context = this.canvas.getContext("2d");
        document.body.append(this.canvas, document.body.childNodes[0]);
        this.frameNo = 0;
        this.interval = setInterval(updateGameArea, 20);
        window.addEventListener('onclick()', function (e) {
          myGameArea.x = e.pageX;
          myGameArea.y = e.pageY;
        })

Ответы [ 2 ]

1 голос
/ 22 февраля 2020

Один из способов достижения наложения сетки, позволяющего вашей игре определить, на какую ячейку сетки щелкнули, - создать отдельные элементы DOM для каждой ячейки сетки, где каждая ячейка выровнена по размеру самой сетки.

Вы можете использовать CSS, чтобы определить общие правила стиля для каждой ячейки сетки, а также использовать селектор :hover, чтобы определить стиль "наведения", чтобы показать ячейку, над которой пользователь наводит курсор:

/* Styling for each tile in grid with absolute 
position against relative wrapper */
.gameAreaWrapper a {
  display:block;
  position: absolute;
  width: 10%;
  height: 10%;
}

/* Cause visual feedback to user when
tile is hovered */
.gameAreaWrapper a:hover {
  background:rgba(255,255,0,0.5);
}

Функция в вашем сценарии будет использовать вложенную l oop для генерации ячеек для сетки 10x10 следующим образом:

function generateGameBoardSquares(wrapper) {

  for(let x = 0; x < 10; x++) {
    for(let y = 0; y < 10; y++) {

      /* Create the cell element */
      const cell = document.createElement("a");

      /* Position relative to top-left corner of parent */
      cell.style.left = `${x*10}%`
      cell.style.top = `${y*10}%`      

      /* Add cell to wrapper parent */
      wrapper.append(cell);
    }  
  }
}

Вот полная демонстрация:

/* Define helper function that generates grid of square
elements across specified wrapper element */
function generateGameBoardSquares(wrapper) {

  function onClick(x,y) {
    alert(`You clicked ${x},${y}`);
  }

  for(let x = 0; x < 10; x++) {
    for(let y = 0; y < 10; y++) {
      
      const tile = document.createElement("a");
      tile.style.left = `${x*10}%`
      tile.style.top = `${y*10}%`      
      tile.addEventListener("click", () => onClick(x,y));
      
      wrapper.append(tile);
    }  
  }
}

var myGameArea = {
  canvas: document.createElement("canvas"),
  start: function() {
    this.canvas.width = 480;
    this.canvas.height = 480;
    this.canvas.style.cursor = "default";
    this.context = this.canvas.getContext("2d");

    const gameAreaWrapper = document.querySelector(".gameAreaWrapper");
    gameAreaWrapper.append(this.canvas);    
    
    /* Cause wrapper to perfectly wrap the canvas that we want 
    to align with */
    gameAreaWrapper.style.width = `${this.canvas.width}px`;
    gameAreaWrapper.style.height = `${this.canvas.height}px`;
    
    /* Generate grid cells */
    generateGameBoardSquares(gameAreaWrapper);

    this.frameNo = 0;
    /*
    this.interval = setInterval(updateGameArea, 20);
    */
    
    /* correct event name is "click" */
    window.addEventListener('click', function(e) {
      myGameArea.x = e.pageX;
      myGameArea.y = e.pageY;
    })
  }
}

myGameArea.start()
/* Added to show grid boundary */
canvas {
  background:rgba(255,0,0,0.1);
}

/* Style wrapper to support placement of 
each tile in grid with relative positioning */
.gameAreaWrapper {
  position: relative;
}

/* Styling for each tile in grid with absolute 
position against relative wrapper */
.gameAreaWrapper a {
  display:block;
  position: absolute;
  width: 10%;
  height: 10%;
}

/* Cause visual feedback to user when
tile is hovered */
.gameAreaWrapper a:hover {
  background:rgba(255,255,0,0.5);
}
<div class="gameAreaWrapper">
  <!--
  Added by your script
  <canvas />
-->
</div>

Надеюсь, это поможет!

1 голос
/ 22 февраля 2020

Ну, вы можете создать изображение с сеткой и наложить его. В противном случае вы можете использовать lineTo, чтобы создать линию в сетке. Затем сделайте это несколько раз, чтобы создать сетку.

let canvas = <link to canvas>;
let context = canvas.getContext('2d');
let gridSize = 10;
let canvasSize = {
    width:400;
    height:400;
}
for(let i=0;i<canvasSize.height;i+=gridSize){
    context.beginPath();
    context.moveTo(i,0);
    context.lineTo(i,canvasSize.height);
    context.strokeStyle = "#222222";
    context.stroke();
}

for(let i=0;i<canvasSize.width;i+=gridSize){
    context.beginPath();
    context.moveTo(0,i);
    context.lineTo(canvasSize.width,i);
    context.strokeStyle = "#222222";
    context.stroke();
}

Я рекомендую проверить: https://www.html5canvastutorials.com/tutorials/html5-canvas-lines/ Мне очень помогли при использовании холстов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...