Перемещение объектов в javascript (начало игры со змеями)

#javascript

#javascript

Вопрос:

У кого-нибудь есть идея, как заставить эти 3 цветных квадрата перемещаться по периметру доски, а не как сейчас, т.е. по строкам? (строки 57-78) https://codepen.io/diana-larussa/pen/ExgpXzo

 function timer() {
    ttl--

    divElement = document.querySelectorAll('div')

    divElement[nr_boxu].style.backgroundColor = "#6d5dfc"
    divElement[nr_boxu].value = 0

    nr_boxu = nr_boxu   1
    divElement[nr_boxu].style.backgroundColor = "#F25270"
    divElement[nr_boxu 1].style.backgroundColor = "#F25270"
    divElement[nr_boxu 2].style.backgroundColor = "#F25270"

    spanTimer.innerHTML = "TIME: "   ttl
    //if (nr_boxu>gridDOMElement.value-4) stop()

    /*if (divElement[nr_boxu] == gridDOMElement.value - 4) {
        divElement[gridDOMElement.value   1].style.backgroundColor = "#F25270"
    }*/

    if (ttl == 0) stop()
}
 

Ответ №1:

Я думаю, что для каждого размера сетки можно сгенерировать последовательность индексов по периметру, и timer() функция может выбрать 4 из этих индексов для обновления.

Например, в этой сетке 5×4:

0 1 2 3 4
5 6 7 8 9
10 11 12 13 14
15 16 17 18 19

perimeter массив будет: [0, 1, 2, 3, 4, 9, 14, 19, 18, 17, 16, 15, 10, 5] (индексы выделены жирным шрифтом)

timer функция выберет 4 индекса из массива, например [0, 1, 2, 3] , в начале, и раскрасит элемент с индексом 0 с #6d5dfc помощью и 1, 2, 3 с #F25270 помощью .

Позже он будет следовать по периметру, например, выбирая 4 элемента: [2, 3, 4, 9] и раскрашивая элемент 2 с #6d5dfc помощью и 3, 4, 9 с #F25270 помощью (нужно быть осторожным при достижении конца массива).

nr_boxu кажется, увеличивается, начиная с 0 при каждом timer() вызове.

Его можно использовать для выбора 4 элементов из perimeter массива, начиная с 0 и заканчивая концом массива.

Следующая формула — nr_boxu % perimeter.length использует оператор остатка для продолжения итерации от 0 до perimeter.length - 1 .

perimeter и timer может быть построен следующим образом:

 function getPerimeter(cols, rows) {
  let res = [];
  // top line: 0, 1, 2, 3, 4
  for (let i = 0; i < cols; i  ) {
    res.push(i);
  }
  // right line: 9, 14
  for (let i = 1; i < rows - 1; i  ) {
    res.push(cols * (i   1) - 1);
  }
  // bottom line: 19, 18, 17, 16, 15
  for (let i = 0; i < cols; i  ) {
    res.push(cols * rows - 1 - i);
  }
  // left line: 10, 15
  for (let i = rows - 2; i > 0; i--) {
    res.push(i * cols);
  }
  return res;
}

let perimeter = getPerimeter(numOfColumns, numOfRows);

function timer() {
    ttl--

    const ind1 = perimeter[nr_boxu % perimeter.length];
    const ind2 = perimeter[(nr_boxu   1) % perimeter.length];
    const ind3 = perimeter[(nr_boxu   2) % perimeter.length];
    const ind4 = perimeter[(nr_boxu   3) % perimeter.length];

    divElement = document.querySelectorAll('div')

    divElement[ind1].style.backgroundColor = "#6d5dfc"
    divElement[ind1].value = 0

    nr_boxu = nr_boxu   1
    divElement[ind2].style.backgroundColor = "#F25270"
    divElement[ind3].style.backgroundColor = "#F25270"
    divElement[ind4].style.backgroundColor = "#F25270"

    spanTimer.innerHTML = "TIME: "   ttl
    //if (nr_boxu>gridDOMElement.value-4) stop()

    /*if (divElement[nr_boxu] == gridDOMElement.value - 4) {
        divElement[gridDOMElement.value   1].style.backgroundColor = "#F25270"
    }*/

    if (ttl == 0) stop()
}