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

如何实现迷宫移动碰撞函数及调整角色初始位置

迷宫开发求助:碰撞检测实现与角色初始位置调整

我正在开发一个可在地图内移动的简易迷宫,已经实现了移动功能,但需要编写一个碰撞函数——当角色触碰颜色为#fff000的区域时触发回弹,目前完全没思路,求帮忙。

另外,当前我控制的核符号角色初始位置在迷宫墙体上,需要调整CSS让它初始位置脱离墙体。

以下是我使用的代码:

JavaScript代码

var objImage;

function init() {
  objImage = document.getElementById("image1");
  objImage.style.position = "relative";
  objImage.style.left = "0px";
  objImage.style.top = "0px";
}

function getKeyAndMove(e) {
  var key_code = e.which || e.keyCode;
  switch (key_code) {
    case 37:
      moveLeft();
      break;
    case 38:
      moveUp();
      break;
    case 39:
      moveRight();
      break;
    case 40:
      moveDown();
      break;
  }
}

function moveLeft() {
  objImage.style.left = parseInt(objImage.style.left) - 17 + "px";
}

function moveUp() {
  objImage.style.top = parseInt(objImage.style.top) - 17 + "px";
}

function moveRight() {
  objImage.style.left = parseInt(objImage.style.left) + 17 + "px";
}

function moveDown() {
  objImage.style.top = parseInt(objImage.style.top) + 17 + "px";
}
window.onload = init;

CSS代码

body {
  background-image: url('https://cdn.glitch.global/db8bf4ca-15e3-46f7-82cc-f9266324510d/Maze%20code%20thingy.png?v=1671163203972');
  background-repeat: no-repeat;
}

HTML代码

<body onkeydown="getKeyAndMove(event)">
  <p></p>
  <img id="image1" src="https://cdn.glitch.global/db8bf4ca-15e3-46f7-82cc-f9266324510d/radioactive%20(1).png?v=1670909277902" lenght="100" width="100" />
</body>

一、调整角色初始位置

直接修改初始定位参数即可,两种方式任选:

方式1:修改CSS

给角色图片添加初始定位样式,替换成你需要的坐标(根据迷宫地图调整):

#image1 {
  position: relative;
  left: 50px;  /* 脱离墙体的X坐标 */
  top: 50px;   /* 脱离墙体的Y坐标 */
}

方式2:修改JS初始化函数

在init函数里直接设置初始位置:

function init() {
  objImage = document.getElementById("image1");
  objImage.style.position = "relative";
  objImage.style.left = "50px";  /* 调整为脱离墙体的X值 */
  objImage.style.top = "50px";   /* 调整为脱离墙体的Y值 */
}

二、实现颜色碰撞检测(回弹功能)

核心思路是通过canvas获取背景图的像素颜色,检测角色移动后是否触碰到#fff000区域,若碰撞则回退到移动前的位置,完整修改后的JS代码如下:

var objImage;
var canvas, ctx;
var mazeImg;

function init() {
  objImage = document.getElementById("image1");
  objImage.style.position = "relative";
  objImage.style.left = "50px";  /* 初始位置调整 */
  objImage.style.top = "50px";

  // 创建隐藏canvas用于像素颜色检测
  canvas = document.createElement('canvas');
  canvas.width = document.body.offsetWidth;
  canvas.height = document.body.offsetHeight;
  canvas.style.display = 'none';
  document.body.appendChild(canvas);
  ctx = canvas.getContext('2d');

  // 加载迷宫背景图到canvas
  mazeImg = new Image();
  mazeImg.src = 'https://cdn.glitch.global/db8bf4ca-15e3-46f7-82cc-f9266324510d/Maze%20code%20thingy.png?v=1671163203972';
  mazeImg.onload = function() {
    ctx.drawImage(mazeImg, 0, 0);
  };
}

// 获取指定坐标的像素十六进制颜色
function getPixelColor(x, y) {
  var pixel = ctx.getImageData(x, y, 1, 1).data;
  return `#${((1 << 24) + (pixel[0] << 16) + (pixel[1] << 8) + pixel[2]).toString(16).slice(1)}`;
}

// 检测角色是否触碰到黄色墙体
function isColliding() {
  var rect = objImage.getBoundingClientRect();
  // 检测角色四个边角的像素,避免漏判
  var checkPoints = [
    {x: rect.left, y: rect.top},
    {x: rect.right, y: rect.top},
    {x: rect.left, y: rect.bottom},
    {x: rect.right, y: rect.bottom}
  ];
  for (var point of checkPoints) {
    var color = getPixelColor(point.x, point.y);
    if (color === '#fff000') {
      return true;
    }
  }
  return false;
}

function getKeyAndMove(e) {
  e.preventDefault(); // 避免按键触发页面滚动
  // 记录移动前的位置,用于碰撞回弹
  var prevLeft = parseInt(objImage.style.left);
  var prevTop = parseInt(objImage.style.top);

  var key_code = e.which || e.keyCode;
  switch (key_code) {
    case 37:
      moveLeft();
      break;
    case 38:
      moveUp();
      break;
    case 39:
      moveRight();
      break;
    case 40:
      moveDown();
      break;
  }

  // 碰撞检测,若触碰黄色区域则回退到原位置
  if (isColliding()) {
    objImage.style.left = prevLeft + "px";
    objImage.style.top = prevTop + "px";
  }
}

function moveLeft() {
  objImage.style.left = parseInt(objImage.style.left) - 17 + "px";
}

function moveUp() {
  objImage.style.top = parseInt(objImage.style.top) - 17 + "px";
}

function moveRight() {
  objImage.style.left = parseInt(objImage.style.left) + 17 + "px";
}

function moveDown() {
  objImage.style.top = parseInt(objImage.style.top) + 17 + "px";
}

window.onload = init;

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 07:40:33