游戏按数组路径走
Game walk by path in array
我正在编写一种算法,用于以给定速度迭代数组的元素。我用它在我找到的路径数组中遍历游戏地图上的单元格。
我需要当用新数组调用新函数时,最后一个函数调用停止工作。
这将用于在单击鼠标时沿路径移动。现在,如果我们调用第一个函数,它会沿着路径走,但如果在路径结束之前,用新路径再次调用该函数,那么它们都将继续改变当前坐标。
对象必须在它第一次调用函数时到达的地方中断它的路径,并在第二次函数调用中继续它的路径。
下面是它现在如何工作的示例代码:
let coord = {x:0,y:0}
let goByPath = (path=[],coord={})=>{
let i = 0;
pathIteration(i,path,coord)
}
let pathIteration = (i,path,coord)=>{
if(i++<path.length){
setTimeout(()=>{
coord = path[i-1];
console.log(coord);
pathIteration(i,path,coord);
},500);
}
return i;
};
path1 = [{x:0,y:1},{x:1,y:1},{x:1,y:2},{x:2,y:2}];
path2 = [{x:1,y:3},{x:1,y:4},{x:1,y:5}];
goByPath(path1, coord);
setTimeout(()=>{
goByPath(path2, coord);
},900);
现在输出到控制台:
{
"x": 0,
"y": 1
}
{
"x": 1,
"y": 1
}
{
"x": 1,
"y": 3
}
{
"x": 1,
"y": 2
}
{
"x": 1,
"y": 4
}
{
"x": 2,
"y": 2
}
{
"x": 1,
"y": 5
}
需要输出:
{
"x": 0,
"y": 1
}
{
"x": 1,
"y": 1
}
{
"x": 1,
"y": 3
}
{
"x": 1,
"y": 4
}
{
"x": 1,
"y": 5
}
你只需要clearTimeout
https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/clearTimeout
let coord = { x: 0, y: 0 };
let myTimeout;
let goByPath = (path = [], coord = {}) => {
let i = 0;
clearTimeout(myTimeout); // stop previous calls
pathIteration(i, path, coord);
}
let pathIteration = (i, path, coord) => {
rect(coord);
if (i++ < path.length) {
myTimeout = setTimeout(() => { // store reference to timeout
coord = path[i - 1];
pathIteration(i, path, coord);
}, 500);
}
return i;
};
/* canvas grid for display purposes */
var canvas = document.querySelector('canvas');
var ctx = canvas.getContext('2d');
var n = 10;
var size = Math.min(innerWidth, innerHeight);
var u = size / n;
var draw = function() {
size = Math.min(innerWidth, innerHeight);
u = size / n;
canvas.width = size;
canvas.height = size;
for (var y = 0; y < n; y++) {
for (var x = 0; x < n; x++) {
ctx.strokeStyle = '#000';
ctx.strokeRect(x * u, y * u, u, u);
}
}
};
draw();
var rect = (coord) => {
ctx.fillStyle = '#888';
ctx.fillRect(coord.x * u, coord.y * u, u, u);
};
/* example */
var path1 = [{x:0,y:1},{x:1,y:1},{x:1,y:2},{x:2,y:2}];
goByPath(path1, coord);
var path2 = [{x:1,y:3},{x:1,y:4},{x:1,y:5}];
setTimeout(() => { goByPath(path2, coord); }, 1600);
body {
margin: 0;
display: grid;
place-content: center;
}
<canvas></canvas>
你可以有一个简单的多线程实现如下:
let coord = { x: 0, y: 0 }
let coordLock = null
let goByPath = (path = [], coord = {}) => {
const newLock = Math.random()
coordLock = newLock
pathIteration(0, path, coord, newLock)
}
let pathIteration = (i, path, coord, lock) => {
if (lock !== coordLock) return i
if (i++ < path.length) {
setTimeout(() => {
coord = path[i - 1]
console.log(coord)
pathIteration(i, path, coord, lock)
}, 500)
}
return i
}
const path1 = [{ x: 0, y: 1 }, { x: 1, y: 1 }, { x: 1, y: 2 }, { x: 2, y: 2 }]
const path2 = [{ x: 1, y: 3 }, { x: 1, y: 4 }, { x: 1, y: 5 }]
goByPath(path1, coord)
setTimeout(() => goByPath(path2, coord), 900)
话虽这么说,但我认为此实现对于此类任务来说很薄弱。对于此类任务,您应该具有适当的面向对象结构。如果此代码库增长,您将来肯定会得到意想不到的结果
要将重要的东西更改为坐标,您不能依赖副作用和全局定义的对象
我正在编写一种算法,用于以给定速度迭代数组的元素。我用它在我找到的路径数组中遍历游戏地图上的单元格。
我需要当用新数组调用新函数时,最后一个函数调用停止工作。
这将用于在单击鼠标时沿路径移动。现在,如果我们调用第一个函数,它会沿着路径走,但如果在路径结束之前,用新路径再次调用该函数,那么它们都将继续改变当前坐标。
对象必须在它第一次调用函数时到达的地方中断它的路径,并在第二次函数调用中继续它的路径。
下面是它现在如何工作的示例代码:
let coord = {x:0,y:0}
let goByPath = (path=[],coord={})=>{
let i = 0;
pathIteration(i,path,coord)
}
let pathIteration = (i,path,coord)=>{
if(i++<path.length){
setTimeout(()=>{
coord = path[i-1];
console.log(coord);
pathIteration(i,path,coord);
},500);
}
return i;
};
path1 = [{x:0,y:1},{x:1,y:1},{x:1,y:2},{x:2,y:2}];
path2 = [{x:1,y:3},{x:1,y:4},{x:1,y:5}];
goByPath(path1, coord);
setTimeout(()=>{
goByPath(path2, coord);
},900);
现在输出到控制台:
{
"x": 0,
"y": 1
}
{
"x": 1,
"y": 1
}
{
"x": 1,
"y": 3
}
{
"x": 1,
"y": 2
}
{
"x": 1,
"y": 4
}
{
"x": 2,
"y": 2
}
{
"x": 1,
"y": 5
}
需要输出:
{
"x": 0,
"y": 1
}
{
"x": 1,
"y": 1
}
{
"x": 1,
"y": 3
}
{
"x": 1,
"y": 4
}
{
"x": 1,
"y": 5
}
你只需要clearTimeout
https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/clearTimeout
let coord = { x: 0, y: 0 };
let myTimeout;
let goByPath = (path = [], coord = {}) => {
let i = 0;
clearTimeout(myTimeout); // stop previous calls
pathIteration(i, path, coord);
}
let pathIteration = (i, path, coord) => {
rect(coord);
if (i++ < path.length) {
myTimeout = setTimeout(() => { // store reference to timeout
coord = path[i - 1];
pathIteration(i, path, coord);
}, 500);
}
return i;
};
/* canvas grid for display purposes */
var canvas = document.querySelector('canvas');
var ctx = canvas.getContext('2d');
var n = 10;
var size = Math.min(innerWidth, innerHeight);
var u = size / n;
var draw = function() {
size = Math.min(innerWidth, innerHeight);
u = size / n;
canvas.width = size;
canvas.height = size;
for (var y = 0; y < n; y++) {
for (var x = 0; x < n; x++) {
ctx.strokeStyle = '#000';
ctx.strokeRect(x * u, y * u, u, u);
}
}
};
draw();
var rect = (coord) => {
ctx.fillStyle = '#888';
ctx.fillRect(coord.x * u, coord.y * u, u, u);
};
/* example */
var path1 = [{x:0,y:1},{x:1,y:1},{x:1,y:2},{x:2,y:2}];
goByPath(path1, coord);
var path2 = [{x:1,y:3},{x:1,y:4},{x:1,y:5}];
setTimeout(() => { goByPath(path2, coord); }, 1600);
body {
margin: 0;
display: grid;
place-content: center;
}
<canvas></canvas>
你可以有一个简单的多线程实现如下:
let coord = { x: 0, y: 0 }
let coordLock = null
let goByPath = (path = [], coord = {}) => {
const newLock = Math.random()
coordLock = newLock
pathIteration(0, path, coord, newLock)
}
let pathIteration = (i, path, coord, lock) => {
if (lock !== coordLock) return i
if (i++ < path.length) {
setTimeout(() => {
coord = path[i - 1]
console.log(coord)
pathIteration(i, path, coord, lock)
}, 500)
}
return i
}
const path1 = [{ x: 0, y: 1 }, { x: 1, y: 1 }, { x: 1, y: 2 }, { x: 2, y: 2 }]
const path2 = [{ x: 1, y: 3 }, { x: 1, y: 4 }, { x: 1, y: 5 }]
goByPath(path1, coord)
setTimeout(() => goByPath(path2, coord), 900)
话虽这么说,但我认为此实现对于此类任务来说很薄弱。对于此类任务,您应该具有适当的面向对象结构。如果此代码库增长,您将来肯定会得到意想不到的结果 要将重要的东西更改为坐标,您不能依赖副作用和全局定义的对象