首页 > 解决方案 > 蛇——穿墙而过

问题描述

我正在为学校制作一个蛇游戏,其中一项任务是让蛇穿过墙壁并从另一侧开始。

newX并且newY是网格上蛇的头部位置(30x30)。我该怎么做呢?

if (
    0 > newX || newX > grid["width"] - 1 ||
    0 > newY || newY > grid["height"] - 1 ||
    getValueFromGrid(newX,newY) === SNAKE
)

标签: javascript

解决方案


这是一个对正数和负数取模的简单函数。
假设宽度是30(并记住索引是从 0 开始的,0...29 = 30 宽度)

  • 如果 x 是-1,则将 x 纠正为29
  • 如果 x 是30,则将 x 纠正为0

const mod = (n, max) => ((n % max) + max) % max;


console.log(mod(29, 30), mod(30, 30), mod(31, 30), mod(32, 30)); // 29, 0, 1, 2
console.log( mod(1, 30),  mod(0, 30), mod(-1, 30), mod(-2, 30)); // 1, 0, 29, 28

像这样使用:

const newX = mod(currentX, width);
const newY = mod(currentY, height);

蛇的例子

使用世界尺寸 9×7 的简单示例:

const mod = (n, max) => ((n % max) + max) % max;

const World = {
  w: 9,
  h: 7,
  el: document.querySelector("#world"),
  render() {
    const map = new Array(this.w * this.h).fill("\u00b7");
    Snake.body.forEach((s, i, b) => map[this.w * s.y + s.x] = i == b.length - 1 ? "\u25a0" : "\u25a1");
    this.el.textContent = map.join("").replace(new RegExp(`(.{${this.w}})`, "g"), "$1\n");
  }
};

const Snake = {
  body: [{x:0,y:0}, {x:1,y:0}, {x:2,y:0}], // [tail, ..., head]
  dir: "R", // L, R, U, D
  speed: 300,
  move() {
    const head = Object.assign(this.body.shift(), this.body[this.body.length-1]); // Convert tail to head
    if (this.dir === "L") head.x = mod(head.x - 1, World.w);
    if (this.dir === "R") head.x = mod(head.x + 1, World.w);
    if (this.dir === "U") head.y = mod(head.y - 1, World.h);
    if (this.dir === "D") head.y = mod(head.y + 1, World.h);
    this.body.push(head);
  }
};

const setDirection = (e) => {
  const d = (e.key.match(/^Arrow(.*)$/)||[])[1];
  if (!d || /UD|DU|LR|RL/.test(`${Snake.dir}${d}`)) return;
  e.preventDefault();
  Snake.dir = d[0];
}

document.addEventListener("keydown", setDirection);

(function engine() {
  Snake.move();
  World.render();
  setTimeout(engine, Snake.speed);
}());
#world{margin: 0; letter-spacing: 0.5em;}
Click here to focus and use arrow keys to move:
<pre id="world">asd</pre>


推荐阅读