javascript - 使用箭头键在网格布局中移动元素
问题描述
我正在创建一个回合制游戏。目前我有一个 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>
解决方案
好问题。
- 首先为每个框分配坐标。
- 基于坐标添加的类(例如 grid-item-01、grid-item-02 等)
- 当前光标的保持位置(最初是 {x: 0, y: 0})
- 对于每次按键,处理位置对象并渲染圆圈。
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>
推荐阅读
- android - 如何减小 Android RadioButton 上可绘制按钮的大小
- css - 使内部图像响应外部 div 大小
- oracle - TomEE-Oracle 连接:连接已关闭
- r - 对于每个 ID,使用 dplyr 根据另一个值更正列的值
- c# - 如何将内置数据类型数组更改为自定义数据类型数组
- laravel - 我无法从 Laravel 中的 put 或 patch 请求中获取输入文件
- ios - xcode 10 总是在情节提要中渲染@2x 图像,这会产生约束问题吗?
- java - Android Studio中getResourceAsStream(credentials.json)时的空指针
- firebase - 如何在 firebase-admin sdk 中更改 FCM 端点
- c# - 打印 RDCL 报告 C#