Автор оригинала: FreeCodeCamp Community Member.
Поскольку технологии развиваются и игровое содержимое стало более алгоритмически созданным, не сложно представить создание жизненного моделирования с уникальным опытом для каждого игрока.
Технологические прорывы, терпение и усовершенствованные навыки приведут нас там, но первый шаг должен понять Процессуальное поколение контента Отказ
Несмотря на то, что существуют многие решения для генерации карты, этот учебник научит вас сделать свой собственный двухмерный генератор карты Dungeon с нуля с помощью JavaScript.
Есть много двухмерных типов карт, и все имеют следующие характеристики:
1. Доступные и недоступные области (туннели и стены).
2. Подключенный маршрут Игрок может ориентироваться.
Алгоритм в этом руководстве поступает из Случайная прогулка алгоритма , одно из простейших решений для генерации карты.
После создания сетки карты стен, этот алгоритм начинается с случайного места на карте. Он продолжает делать туннели и принимать случайные повороты, чтобы завершить желаемое количество туннелей.
Чтобы увидеть демонстрацию, откройте проект CodePen ниже, нажмите на карту, чтобы создать новую карту и изменить следующие значения:
- Размеры: ширина и высота карты.
- MaxTunnels: Наибольшее количество поворотов, алгоритм может занять карту.
- Maxlength: Наибольшая длина каждого туннеля алгоритм выберет перед тем, как сделать горизонтальный или вертикальный поворот.
Примечание: Чем больше Maxturn сравнивается с размерами, плотнее карта будет. Чем больше Maxlength сравнивается с размерами, тем больше «туннель-y» она будет выглядеть.
Далее давайте пройдемся через алгоритм генерации карты, чтобы увидеть, как это:
- Делает двумерную карту стен
- Выбирает случайную отправную точку на карте
- Хотя количество туннелей не ноль
- Выбирает случайную длину от максимально допустимой длины
- Выбирает случайное направление, чтобы повернуть (вправо, влево, вверх, вниз)
- Рисует туннель в этом направлении, избегая краев карты
- Уменьшает количество туннелей и повторяет во время петли
- Возвращает карту с изменениями
Эта петля продолжается до тех пор, пока количество туннелей не равна нулю.
Алгоритм кода
Поскольку карта состоит из туннельных и стеновых клеток, мы могли бы описать его как Zeros и в двухмерном массиве, как следующее:
map = [[1,1,1,1,0], [1,0,0,0,0], [1,0,1,1,1], [1,0,0,0,1], [1,1,1,0,1]]
Поскольку каждая ячейка находится в двухмерном массиве, мы можем получить доступ к его значению, узнав его ряд и столбец, такой как карта [ROW] [колонна].
Перед записью алгоритма вам нужен функция помощника, которая принимает символ и измерение в качестве аргументов и возвращает двумерный массив.
createArray(num, dimensions) { var array = []; for (var i = 0; i < dimensions; i++) { array.push([]); for (var j = 0; j < dimensions; j++) { array[i].push(num); } } return array; }
Для реализации алгоритма случайного прогулка установите размеры карты (ширина и высоту), MaxTunnels
Переменная и Maxlength
Переменная.
createMap(){ let dimensions = 5, maxTunnels = 3, maxLength = 3;
Затем сделайте двумерный массив, используя предопределенную функцию помощника (двумерный массив из них).
let map = createArray(1, dimensions);
Настройте случайную колонку и случайную строку для создания случайной отправной точки для первого туннеля.
let currentRow = Math.floor(Math.random() * dimensions), currentColumn = Math.floor(Math.random() * dimensions);
Чтобы избежать сложности диагональных поворотов, алгоритм необходимо указать горизонтальные и вертикальные направления. Каждая клетка находится в двухмерном массиве и может быть идентифицировано с его рядкой и столбцом. Из-за этого направления могут быть определены как вычитания из и/или дополнения к колонне и номера строк.
Например, чтобы перейти к ячейке вокруг клетки [2] [2], вы можете выполнить следующие операции:
- идти вверх Вычтите 1 от его ряда [1] [2]
- идти вниз добавьте 1 к его строке [3] [2]
- идти правильно Добавьте 1 в его колонку [2] [3]
- идти левый вычитайте 1 из его колонны [2] [1]
Следующая карта иллюстрирует эти операции:
Теперь установите Указания
Переменная к следующим значениям, что алгоритм выберет из перед созданием каждого туннеля:
let directions = [[-1, 0], [1, 0], [0, -1], [0, 1]];
Наконец, инициировать случайное направление
Переменная, чтобы удерживать случайное значение из массива направлений и установить lastirection
переменная к пустому массиву, которое будет держать старше случайное направление
значение.
Примечание: lastirection
Массив пуст в первой петле, потому что нет старшего случайное направление
значение.
let lastDirection = [], randomDirection;
Далее убедитесь, что Maxtunnel
не ноль и размеры и Maxlength
значения были получены. Продолжайте поиск случайных направлений, пока не найдете ни одного обратного или идентичного для lastirection
Отказ Это делать пока цикла Помогает предотвратить перезаписи недавно нарисованного туннеля или рисуя два туннеля спина к спине.
Например, если ваш LastTurn
это [0, 1], то пока петля предотвращает двигаться вперед, пока случайное направление
устанавливается на значение, которое не является [0, 1] или противоположным [0, -1].
do { randomDirection = directions[Math.floor(Math.random() * directions.length)]; } while ((randomDirection[0] === -lastDirection[0] && randomDirection[1] === -lastDirection[1]) || (randomDirection[0] === lastDirection[0] && randomDirection[1] === lastDirection[1]));
В цикле DO пока есть два основных условия, которые разделены на (Или) знак. Первая часть состояния также состоит из двух условий. Первый проверяет, если
случайное направление Первый предмет - это обратное
lastirection ‘s Первый предмет. Второй проверяет, если
случайное направление второй предмет - это обратное
LastTurn
Чтобы проиллюстрировать, если lastirection
это [0,1] и случайное направление
[0, -1], первая часть состояния проверяет, если случайное направление
[0] === – lastirection
[0]), что приводит к 0 === – 0 и верно.
Затем он проверяет, если ( randerDirection
[1] === – lastirection
[1]), который соответствует (-1 === -1) и также правда. Поскольку оба условия верны, алгоритм возвращается, чтобы найти другой случайное направление
Отказ
Вторая часть состояния проверяет, если первые и вторые значения обоих массивов одинаковы.
После выбора случайное направление
Это удовлетворяет условиям, установить переменную случайным образом выбирать длину от Maxlength
Отказ Установить Tunnellength
Переменная к нулю на сервер как итератор.
let randomLength = Math.ceil(Math.random() * maxLength), tunnelLength = 0;
Сделайте туннель, повернув значение клеток от одного до нуля, а Tunnellength
меньше, чем randomlength
Отказ Если внутри цикла туннель попадает в края карты, петля должна сломаться.
while (tunnelLength < randomLength) { if(((currentRow === 0) && (randomDirection[0] === -1))|| ((currentColumn === 0) && (randomDirection[1] === -1))|| ((currentRow === dimensions — 1) && (randomDirection[0] ===1))|| ((currentColumn === dimensions — 1) && (randomDirection[1] === 1))) { break; }
Еще установить текущую ячейку карты на ноль, используя нынешнее
и stockcolumn.
Добавьте значения в случайное направление
Массив, установив нынешнее
и CurrentColumn
где они должны быть в предстоящей итерации цикла. Теперь увеличить Tunnellength
итератор.
else{ map[currentRow][currentColumn] = 0; currentRow += randomDirection[0]; currentColumn += randomDirection[1]; tunnelLength++; } }
После того, как цикл делает туннель или разрывы, ударив краю карты, проверьте, если туннель длиной не менее одного блока. Если это так, установите lastirection
к случайное направление
и уменьшение MaxTunnels
и вернуться, чтобы сделать другой туннель с другим случайное направление
Отказ
if (tunnelLength) { lastDirection = randomDirection; maxTunnels--; }
Это, если заявление предотвращает цикл для цикла, который попал в край карта и не сделал туннель по меньшей мере одной ячейки для уменьшения Maxtunnel
и изменить lastirection
Отказ Когда это произойдет, алгоритм идет, чтобы найти другой случайное направление
продолжать.
Когда он заканчивает рисование туннелей и MaxTunnels
равен нулю, вернуть полученную карту со всеми его поворотами и туннелями.
} return map; };
Вы можете увидеть полный алгоритм в следующем фрагменте:
Поздравляем для чтения этого учебника. Теперь вы хорошо оснащены, чтобы сделать свой собственный генератор карты или улучшить эту версию. Проверьте проект на Кодепен и на Github как приложение React.
Спасибо за прочтение! Если вам понравилась эта история, не забудьте поделиться этим в социальных сетях.
Особая благодарность Том Для сопротивления этой статьи.