首页 > 解决方案 > 使用箭头键在网格布局中移动元素

问题描述

我正在创建一个回合制游戏。目前我有一个 16*16 的网格。我有一个所有四个箭头键的事件监听器。我在第一个网格项目中放置了一个圆圈。我想用箭头键一次移动一个网格单元格。我无法理解我该怎么做。我想我应该有一个变量来跟踪圆圈。但是如何通过按键将其移动到另一个单元格?

const container = document.querySelector(".grid");
const gridNodes = document.querySelectorAll(".grid-item");
const gridArray = Array.from(gridNodes);
let circle = document.createElement("div");


function makeGrid(rows, cols) {
  container.style.setProperty("--grid-rows", rows);
  container.style.setProperty("--grid-cols", cols);
  for (let c = 0; c < rows * cols; c++) {
    let cell = document.createElement("div");
    container.appendChild(cell).className = "grid-item";
  }
}
const keys = {
  left: 37,
  up: 38,
  right: 39,
  down: 40
};
makeGrid(16, 16);
circle.style.width = "20px";
circle.style.height = "20px";
circle.style.backgroundColor = "#000";
let firstGridItem = document.querySelector(".grid-item");
firstGridItem.appendChild(circle);
function moveRight(e) {
  console.log(gridArray);
}
function handleKey(e) {
  switch (e.keyCode) {
    case keys.left:
      console.log("left ");
      break;
    case keys.up:
      console.log("up ");
      break;

    case keys.right:
      moveRight(e);
      break;

    case keys.down:
      console.log("down ");
      break;
  }
}
window.addEventListener("keydown", handleKey);
:root {
  --grid-cols: 1;
  --grid-rows: 1;
}

.container {
  display: grid;
  grid-template-rows: repeat(var(--grid-rows), 1fr);
  grid-template-columns: repeat(var(--grid-cols), 1fr);
}

.grid-item {
  
  padding: 1em;
  border: 1px solid #ddd;
  text-align: center;
}
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta http-equiv="X-UA-Compatible" content="ie=edge" />
    <title>Turn Base Game</title>

    <link rel="stylesheet" href="bundle.css" />
  </head>
  <body>
    <h1 class="text-center text-white">Turn Based Board Game</h1>
    <main class="map">
      <div class="container grid"></div>
    </main>
    <script src="bundle.js"></script>
  </body>
</html>

标签: javascript

解决方案


好问题。

  1. 首先为每个框分配坐标。
  2. 基于坐标添加的类(例如 grid-item-01、grid-item-02 等)
  3. 当前光标的保持位置(最初是 {x: 0, y: 0})
  4. 对于每次按键,处理位置对象并渲染圆圈。

const container = document.querySelector(".grid");
const gridNodes = document.querySelectorAll(".grid-item");
const gridArray = Array.from(gridNodes);
let circle = document.createElement("div");
let position = {x: 0, y: 0};


function makeGrid(rows, cols) {
  container.style.setProperty("--grid-rows", rows);
  container.style.setProperty("--grid-cols", cols);
  
  let x = 0;
  let y = 0;
  for (let c = 0; c < rows * cols; c++) {
    let cell = document.createElement("div");
    
    y = c%cols;
    
    if (y === (rows - 1)) {
    	x++;
    }    
        
    container.appendChild(cell).className = "grid-item grid-item-" + x + '' + y;
  }
}
const keys = {
  left: 37,
  up: 38,
  right: 39,
  down: 40
};
makeGrid(16, 16);
circle.style.width = "20px";
circle.style.height = "20px";
circle.style.backgroundColor = "#000";
let firstGridItem = document.querySelector(".grid-item");
firstGridItem.appendChild(circle);

function handleKey(e) {
  switch (e.keyCode) {
    case keys.left:
      position.y--;
      break;
    case keys.up:
      position.x--;
      break;

    case keys.right:
      position.y++;
      break;

    case keys.down:
      position.x++;
      break;
  }
  
  let gridItem = document.querySelector(".grid-item-" + position.x + '' + position.y);
  gridItem.appendChild(circle);
}
window.addEventListener("keydown", handleKey);
:root {
  --grid-cols: 1;
  --grid-rows: 1;
}

.container {
  display: grid;
  grid-template-rows: repeat(var(--grid-rows), 1fr);
  grid-template-columns: repeat(var(--grid-cols), 1fr);
}

.grid-item {
  
  padding: 1em;
  border: 1px solid #ddd;
  text-align: center;
}
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta http-equiv="X-UA-Compatible" content="ie=edge" />
    <title>Turn Base Game</title>

    <link rel="stylesheet" href="bundle.css" />
  </head>
  <body>
    <h1 class="text-center text-white">Turn Based Board Game</h1>
    <main class="map">
      <div class="container grid"></div>
    </main>
    <script src="bundle.js"></script>
  </body>
</html>


推荐阅读