javascript - 蛇——穿墙而过
问题描述
我正在为学校制作一个蛇游戏,其中一项任务是让蛇穿过墙壁并从另一侧开始。
newX
并且newY
是网格上蛇的头部位置(30x30)。我该怎么做呢?
if (
0 > newX || newX > grid["width"] - 1 ||
0 > newY || newY > grid["height"] - 1 ||
getValueFromGrid(newX,newY) === SNAKE
)
解决方案
这是一个对正数和负数取模的简单函数。
假设宽度是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>
推荐阅读
- algorithm - Go中几乎增加序列:如何循环避免索引超出范围?
- spring - 将资源文件夹中文件的路径传递给spring bean定义
- c# - c# Selenium youtube Search sendkeys
- perl - 如何使用这个 perl one liner 找到 4 位 unicode 字符?
- listview - 使用 scenebuilder/fxml 添加到 Listview 的问题
- c - 以下代码如何工作 printf("%c")?
- javascript - 函数返回多个值
- json - 在服务器上加载 CSV 数据,将数据转换为 JSON 并使用 Golang 使用 Json 查询获取结果
- rust - 变量不需要是可变的,但它确实
- python - 如何在kivymd中以矩阵形式获取用户输入