Игра прогулка по дорожке в массиве - PullRequest
7 голосов
/ 27 июня 2019

Я пишу алгоритм для перебора элементов массива с заданной скоростью.Я использую это для перебора ячеек игровой карты в массиве путей, которые я нахожу.

Мне нужно, чтобы при вызове новой функции с новым массивом последний вызов функции перестал работать.

Это будет использоваться для перемещения по траектории одним щелчком мыши.Теперь, если мы вызовем первую функцию, она пойдет по пути, но если до конца пути функция будет вызвана снова с новым путем, то они оба продолжат изменять текущую координату.

Объект должен прервать свой путь в том месте, куда он пришел, когда он впервые вызвал функцию, и продолжить свой путь во втором вызове функции.

Вот пример кода того, как он работает сейчас:

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
}

Ответы [ 2 ]

4 голосов
/ 27 июня 2019

Вам просто нужно 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>
0 голосов
/ 27 июня 2019

Вы можете создать простую многопоточную реализацию следующим образом:

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)

При этом, я думаю, что эта реализация слаба для такой задачи.Вы должны иметь правильную объектно-ориентированную структуру для такой задачи.Если эта база кода будет расти, в будущем вы наверняка получите неожиданные результаты. Чтобы изменить важную вещь в качестве координат, вы не можете полагаться на побочные эффекты и глобально определенные объекты

...