Манипуляции с массивами, и тигры, и медведи, о боже!
Проблема
Один аспект моей игровой сетки, который мне не нравился, заключался в том, что если пользователь выбрал несколько ячеек, а затем изменил размер сетки, ячейки прыгали по всей доске. При создании логики рендеринга я понимал, что это произойдет, но я решил оставить это в ледяном ящике, пока все не будет в основном работать.
Допустим, пользователь выбрал эту милую маленькую букву Т:
Если они увеличили размер сетки, когда симпатичный маленький T превратился в беспорядок:
Или, если кто-то выбрал этот маленький крестик с квадратом из большей сетки:
И решили довольно резко уменьшить размер сетки, они в конечном итоге не только измельчают, но и переставляют:
Это выглядит не очень хорошо, не так ли?
Исправление 1 - Рост сетки
Исправить это было относительно легко, потому что у меня уже была функция, которая переворачивала плоскую сетку ячеек:
В массив с накоплением:
Сначала я думал только об обновлении плоского массива, точно определяя, сколько индексов будет вставлено перед первой ячейкой, а затем между 6-й и 7-й и т. Д. Я быстро понял, что если бы я просто превратил их в отдельные фрагменты, я возможно, можно было бы быстрее объединить каждый измененный массив вместе.
Мой growCellArray(array, alpha)
принимает два аргумента. Исходный плоский массив и альфа того, сколько ячеек нужно добавить к общей ширине / высоте массива. Я начинаю с массива 5x5 и передаю alpha
из 2, создавая массив 7x7.
Я знаю, что нам нужно будет сложить массив мертвых ячеек вверху и внизу, поэтому сначала создайте его.
- Я довольно часто использую метод Array.from () на протяжении всего проекта, поэтому зациклился на нем.
- Мы можем получить размеры сетки, получив квадратный корень из длины сглаженного массива, который затем я могу добавить альфа, чтобы получить длину новой строки.
Затем нам нужно обработать обновление уже существующих массивов, которые могут иметь или не иметь активных ячеек, выбранных пользователем. Все, что изменяется в этих строках, - это передняя и конечная части массивов. К каждой стороне всегда будет добавлено дополнительное количество alpha
/ 2 ячеек.
Таким образом, я конвертирую плоский массив в его подмассивы, а затем заполняю каждую сторону новыми ячейками. Оператор распространения делает это проще простого.
Возврат был немного сложнее, потому что я мог просто распределить их вместе, потому что мой раздел updatedRows представляет собой единый массив других массивов. Итак, мне нужно объединить их вместе.
Итак, теперь это:
Становится меньшей T, сохраняя своих соседей и относительное положение:
Исправление 2 - сжатие сетки
Сжатие работает по-разному, потому что части массива разрушаются на каждом ходу. Однако нужны те же аргументы. array
текущего состояния и alpha
, представляющие то, что мы будем отрубать.
- Сначала я разбиваю все на их подмассивы.
- Затем я возвращаю массив с удаленными первым и последним разделами для каждого подмассива.
- Затем я фильтрую все подмассивы и избавляюсь от первого и последнего.
- Затем я собрал все массивы вместе, чтобы получить сплющенный массив, который использует мой рендеринг.
Примечание
Здесь я объединяю несколько разных методов вместе, а также использую тройной, но я стараюсь, чтобы такие вещи были удобочитаемыми. Правильный интервал и название имеют решающее значение для понимания вещей позже. Иногда я просматриваю переполнение стека и вижу сообщения, в которых есть несколько символов, использованных для создания чего-либо. Как, черт возьми, это полезно? Я полагаю, что приведенный выше пример мог бы быть сложным, если бы кто-то не был знаком с различными методами массива, поэтому комментарии могут быть полезны в этом случае. Избегая семантических проблем, связанных с правильным именованием каждого шага редактирования, можно избежать путаницы, если я выберу нелепые имена переменных. Мне нравится хорошее сочетание правильно названных переменных для хранения вещей и связанных вместе методов в более сложных сценариях.
Вот продукт нашей окончательной функции усадки. Наши T и Square меняются с:
К большему относительно позиционированию:
В текущей итерации, если клетки перемещаются за пределы игрового поля, они удаляются безвозвратно. Я могу решить сохранить эти удаленные ячейки до тех пор, пока не будет нажата кнопка «Пуск», но пока я оставлю это в своем холодильнике.
Еще не все!
Первоначально опубликовано на gist.github.com.