Я написал небольшую 2D-игру в javascript, которая использует сетку, где игрок начинает в позиции [0,0] и может перемещать почти бесконечное расстояние в любом направлении.Отрицательные координаты в сетке на основе игры
Теперь я хочу реализовать A * pathfinding, но у меня возникли проблемы с поиском лучшего способа сохранить мир со всеми его различными препятствиями, врагами и ландшафтом. Это то, о чем я уже пробовал или думал.
Массив массивов
Здесь я храню мир в массиве массивов [x][y]
.
var world = [[]];
world[312][11] = 0;
world[312][12] = 0;
world[312][13] = 1;
world[312][14] = 1;
...
Это прекрасно работает с A * pathfinding! Легко и очень быстро получить доступ к определенной координате и заполнить мир. В приведенном выше примере я просто храню проходимую (0) или непроходимую (1) местность, но я могу хранить почти все, что захочу. Однако это не очень хорошо работает с отрицательными координатами, например, если мои игроки находятся в [-12][-230]
. Отрицательные ключи в массиве javascript на самом деле не являются частью массива, они не будут включены в world.length
или world[3].length
, и, насколько я понимаю, это общая плохая практика и может также повлиять на производительность. Я где-то читал, что если вы используете отрицательные ключи в своем массиве, вы делаете это неправильно. Я по-прежнему не мог бы передать весь мир в функцию A * по очевидным причинам. Просто небольшая часть, близкая к моему игроку, но координаты будут соответствовать позициям в массиве, с которыми легко работать.
отдельный массив массивов только для A * Pathfinding
Это где я нахожусь сейчас. У меня есть отдельная сетка 50x50 под названием pathMap = [[]]
, то есть только используется для поиска пути.
var pathMap = [[]];
pathMap[0][0] = 0;
pathMap[0][1] = 0;
pathMap[0][2] = 1;
pathMap[0][3] = 1;
...
Она начинается в pathMap[0][0]
и идет в pathMap[50][50]
и работает в качестве наложения на моей текущей позиции, где я (как игрок) всегда будет находиться в центральном положении. Мои real координаты могут быть чем-то вроде [-5195,323]
, но это переводит на pathMap[25][25]
, и все, что близко ко мне, помещается в путьМарт по отношению к моей позиции. Теперь это работает, но это огромный беспорядок. Все переводы от одной координаты к другой взад и вперед заставляют мой мозг болеть. Кроме того, когда я получаю путь назад от A *, я должен перевести каждый его шаг назад в фактическую позицию, в которой мой элемент должен перемещаться в реальном мире. Я также должен заполнить один и тот же объект на 2 разных сетках при каждом обновлении, что также ухудшает производительность.
Массив объектов
Я думаю, что это то, где я хочу быть, но у меня есть некоторые проблемы с этим, а также.
var world = [];
world[0] = { x: -10, y: 3, impassable: 0 };
world[1] = { x: -10, y: 4, impassable: 0 };
world[2] = { x: -10, y: 5, impassable: 1 };
world[3] = { x: -10, y: 6, impassable: 1 };
...
Прекрасно работает с отрицательными значениями x или y! Однако в этом массиве не так легко найти, например, [10,3]
. Мне нужно пройти весь массив, чтобы искать объект, где x == 10
и y == 3
вместо очень простого и быстрого подхода world[10][3]
в первом примере.Кроме того, я не могу полагаться на то, что координаты находятся в правильном порядке, используя эту версию, сортировка становится сложнее, так же как и другие вещи, которые намного проще с массивом массивов.
Перестроить игру, чтобы всегда быть на положительной стороне
Я бы предпочел не делать этого, но я рассмотрел размещение игроков, начиная позиции на что-то вроде [1000000,1000000]
вместо этого, и делают отрицательные координаты вне пределов. Кажется неудачным, если мне нужно устранить видение, которое у меня есть бесконечность, чтобы сделать работу по обращению с меньшим количеством кода. Я знаю, что всегда будут какие-то верхние или нижние ограничения, но я просто хочу начать с [0,0], а не с некоторой произвольной координатой по причинам, связанным с массивом.
Другое?
В javascript есть ли другой вариант, который работает лучше и не описан выше? Я очень открыт для предложений!
Есть ли передовая практика для подобных случаев?
Будет ли это работать, если вы сделаете мир объекта с ключом будучи 'X; Y':' мир = {}; мир ['- 10; -10'] = 0'? Или создавайте объекты объектов, поэтому 'world [10] [10]' будет работать как массив. – elmigranto
Интересно! Подобно * массиву объектов * версии с простотой, чтобы найти определенную координату массива * массивов *. Мне это нравится, но по какой-то причине он чувствует себя грязным. Я думаю, что это конкатенация и разделение ключа, который меня отталкивает. –
'world = {}; мир [-10] = {}; мир [-10] [- 10] = 0'. Вам нужно будет сохранить свои собственные свойства 'length' и методы Array.prototype (если вам нужно что-то вроде' forEach' в вашем 'мире'). Это можно сделать при генерации или с помощью специального метода для добавления координат в 'world' или с помощью seters/getters. Я не думаю, что было бы много штрафа по сравнению с «Array [Array]», поскольку массивы - это в основном объекты с разными прототипами. – elmigranto