You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何防止角色移出grid-container?网格容器边界控制实现

限制角色移出Grid容器的边界解决方案

项目背景

我正在开发一个包含角色与网格模板的简单项目,核心逻辑是角色通过WASD按键移动时,同步位移网格容器insideBox(当角色触达视口边缘时触发网格位移)。但目前角色可以移出insideBox的网格范围(灰色区域代表超出网格),需要实现角色无法移出该容器,超出时不触发任何位移变化。

现有HTML代码:

<html>
<head>
    <script defer src="main.js"></script>
    <link rel="stylesheet" href="main.css">
</head>
<body>
<div class="box">
    <img id="inFront" src="inFront.png" width="200px">

    <div id="insideBox" class="insideBox"> 
        <div id="pageOne" class="pageOne"></div>
        <div id="pageTwo" class="pageTwo"></div>
        <div id="pageThree" class="pageThree"></div>
        <div id="pageFour" class="pageFour"></div>
        <div id="pageFive" class="pageFive"></div>
        <div id="pageSix" class="pageSix"></div>
        <div id="pageSeven" class="pageSeven"></div>
        <div id="pageEight" class="pageEight"></div>
        <div id="pageNine" class="pageNine"></div>
    </div>

</div>
</body>
</html>

现有CSS代码:

img {
    position: absolute;
    z-index: 99;
}

body {
    overflow-x: hidden;
    overflow-y: hidden;
    width: 100vw;
    height: 100vh;
}

.box {
    width: 99vw;
    height: 99vh;   
    background-color: gray;
    z-index: -1;
}

.insideBox {
    display: grid;
    grid-template-columns: 1fr 1fr 1fr;
    grid-template-rows: 1fr 1fr 1fr;
    width: 300vw;
    height: 300vh;
    position: relative;
}

解决方案

核心逻辑

通过计算角色相对于网格容器的绝对位置,在每次移动前判断目标位置是否超出网格边界,只有在合法范围内才执行位移操作,同时限制网格容器的最大位移范围,确保角色始终处于网格内部。

具体实现

  1. 添加JavaScript边界控制逻辑
    在main.js中写入以下代码:
const player = document.getElementById('inFront');
const gridContainer = document.getElementById('insideBox');
const viewportWidth = window.innerWidth;
const viewportHeight = window.innerHeight;
const gridWidth = gridContainer.offsetWidth;
const gridHeight = gridContainer.offsetHeight;

// 初始化位置变量
let playerX = 0;
let playerY = 0;
let gridX = 0;
let gridY = 0;
const moveStep = 20; // 每次移动的步长

// 监听WASD按键
document.addEventListener('keydown', (e) => {
  let newPlayerX = playerX;
  let newPlayerY = playerY;
  let newGridX = gridX;
  let newGridY = gridY;

  // 根据按键计算目标位置
  switch(e.key.toLowerCase()) {
    case 'w':
      newPlayerY -= moveStep;
      // 角色触达视口顶部时,尝试上移网格
      if (newPlayerY < 0) {
        newGridY += moveStep;
        // 网格上移的最大限制:网格底部不能低于视口底部
        newGridY = Math.min(newGridY, gridHeight - viewportHeight);
        // 角色保持在视口顶部
        newPlayerY = 0;
      }
      break;
    case 's':
      newPlayerY += moveStep;
      // 角色触达视口底部时,尝试下移网格
      if (newPlayerY > viewportHeight - player.offsetHeight) {
        newGridY -= moveStep;
        // 网格下移的最大限制:网格顶部不能高于视口顶部
        newGridY = Math.max(newGridY, 0);
        // 角色保持在视口底部
        newPlayerY = viewportHeight - player.offsetHeight;
      }
      break;
    case 'a':
      newPlayerX -= moveStep;
      if (newPlayerX < 0) {
        newGridX += moveStep;
        newGridX = Math.min(newGridX, gridWidth - viewportWidth);
        newPlayerX = 0;
      }
      break;
    case 'd':
      newPlayerX += moveStep;
      if (newPlayerX > viewportWidth - player.offsetWidth) {
        newGridX -= moveStep;
        newGridX = Math.max(newGridX, 0);
        newPlayerX = viewportWidth - player.offsetWidth;
      }
      break;
  }

  // 计算角色相对于网格容器的绝对位置,判断是否超出边界
  const playerAbsLeft = newPlayerX - newGridX;
  const playerAbsTop = newPlayerY - newGridY;
  const isWithinGrid = 
    playerAbsLeft >= 0 && 
    playerAbsLeft <= gridWidth - player.offsetWidth && 
    playerAbsTop >= 0 && 
    playerAbsTop <= gridHeight - player.offsetHeight;

  // 只有在网格范围内才更新位置
  if (isWithinGrid) {
    playerX = newPlayerX;
    playerY = newPlayerY;
    gridX = newGridX;
    gridY = newGridY;

    player.style.left = `${playerX}px`;
    player.style.top = `${playerY}px`;
    gridContainer.style.transform = `translate(${gridX}px, ${gridY}px)`;
  }
});
  1. 可选:添加网格子元素样式(便于可视化)
    在CSS中添加网格子元素的样式,方便观察网格边界:
.pageOne, .pageTwo, .pageThree,
.pageFour, .pageFive, .pageSix,
.pageSeven, .pageEight, .pageNine {
  border: 1px solid #ffffff;
  background-color: #666666;
}

效果说明

  • 角色在视口内自由移动,触达视口边缘时会带动网格容器位移
  • 当网格容器位移到极限位置(无法再移动)时,角色无法继续向该方向移动,不会超出网格范围
  • 所有位移操作仅在角色处于网格内部时生效

内容的提问来源于stack exchange,提问作者repinSlun

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.03 07:55:20