Алгоритм создания игровой карты из отдельных изображений - PullRequest
3 голосов
/ 20 сентября 2008

Я разрабатываю игру для браузера.

Игра космическая тема и мне нужно сгенерировать карту "Галактики".

Основная идея карты здесь:

игровая карта http://www.oglehq.com/map.png

Карта представляет собой сетку, где каждый сектор сетки может содержать планету / систему, и каждая из них имеет ссылки на несколько соседних сеток.

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

Чтобы создать новую карту, я бы «сплел» изображения вместе. Изображения элементов карты будут иметь планеты и их ссылки уже на них, и поэтому мне необходимо сшить карту таким образом, чтобы каждое изображение располагалось с соответствующими аналогами =>, поэтому изображение в нижнем углу должно иметь изображения слева и по диагонали слева, которые связаны с ним правильно.

Как бы вы создали код, чтобы знать, где разместить изображения? Есть ли лучший способ, чем использовать изображения?

На данный момент производительность и / или нагрузка не должны рассматриваться (если мне нужно генерировать карты для предварительной конфигурации, а не в реальном времени, я не против).

Если что-то изменится, я буду использовать HTML, CSS и JavaScript и поддерживаться приложением Ruby on Rails.

Ответы [ 7 ]

3 голосов
/ 20 сентября 2008

Существует два очень хороших графических пакета, управляемых вектором / javascript, которые практически универсальны: SVG и VML. Как правило, они производят высококачественные векторные изображения с низкой пропускной способностью.

SVG поддерживается Firefox, Opera, Safari и Chrome - технически поддерживается только часть спецификации, но для практических целей вы должны иметь возможность делать то, что вам нужно. У w3schools есть хороший справочник для изучения / использования svg .

VML - это ответ Microsoft на SVG, и (удивительно) изначально поддерживается IE, хотя SVG нет. Msdn имеет лучшую ссылку для vml .

Хотя это больше работы, вы могли бы написать две аналогичные / несколько интегрированные базы кода для этих двух технологий. Реальное преимущество заключается в том, что пользователям не нужно ничего устанавливать, чтобы играть в вашу игру онлайн - она ​​просто будет работать для 99,9% всех пользователей.

Кстати, вы говорите, что запрашиваете алгоритм, а я предлагаю технологии (если это правильный термин для SVG / VML). Если бы вы могли уточнить спецификацию ввода / вывода и, возможно, какая часть представляет проблему (например, какая наивная реализация не сработает и почему), это прояснит вопрос и, возможно, даст более сфокусированные ответы.

Добавление Тег canvas становится все более широко поддерживаемым, за исключением заметного IE. Это может быть более чистый способ встраивания графических элементов в HTML.

Полезные материалы для холста: Учебник по холстам в Opera | Учебник по холстам в Mozilla | частичная реализация canvas-in-IE

2 голосов
/ 20 сентября 2008

Хм. Если каждый блок может ссылаться только на свои 8 соседей, то у вас есть только 2 ^ 8 = 256 типов плиток. Меньше, если вы ограничите количество возможных ссылок из любой плитки.

Вы можете закодировать, какие ссылки присутствуют на изображении, используя имя из 8 символов:

11000010.jpeg

Или сохраните несколько байтов и преобразуйте их в десятичное или шестнадцатеричное

196.jpg

Тогда код. Есть много способов представить карту для внутреннего использования. Одним из способов является создание объекта для каждой планеты. Объект планеты знает свое положение в сетке и положение связанных планет. Следовательно, у него достаточно информации, чтобы выбрать подходящий файл.

Или иметь двумерный массив. Чтобы определить, какое изображение показывать для каждого элемента массива, посмотрите на 8 соседних элементов массива. Если вы сделаете это, вы можете избежать кодирования границ, увеличив массив на две оси по обеим осям и имея пустую «границу» по краям. Это избавит вас от проверки, находится ли соседний элемент массива вне массива.

1 голос
/ 20 сентября 2008

Есть два способа представить вашу карту.

Один из способов представить это сетка квадратов, где каждый квадрат может иметь планету / систему или нет. Затем можно указать, что если сосед находится на расстоянии одного квадрата в любом из восьми направлений (NW, N, NE, W, E, SW, S, SE), то существует связь с этим соседом. Однако, обратите внимание, что на вашем примере карты центральная система не подключена к системе к северу / востоку от нее, поэтому, возможно, это не то представление, которое вам нужно. Но его можно использовать для построения другого представления

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

Итак, в вашем примере сетки 3х3 данные будут:

 Tile   Connections
        nw  n ne  w  e sw  s se
 nw      0  0  0  0  0  0  0  0 
 n       0  0  0  0  1  0  1  0
 ne      0  0  0  1  0  0  0  0
 w       0  0  0  0  0  0  0  0
 center  0  1  0  0  0  0  1  1
 e       0  0  0  0  0  0  0  0
 se      0  0  0  0  0  0  0  0
 s       0  1  0  0  1  0  0  0
 sw      1  0  0  1  0  0  0  0

Вы могли бы представить эти соединения в виде массива из восьми логических значений или гораздо более компактно как восьмибитное целое число.

Тогда легко использовать восемь логических значений (или восьмибитное целое), чтобы сформировать имя файла растрового изображения для загрузки для этого квадрата сетки. Например, ваш центральный фрагмент, использующий эту схему, может называться «Bitmap01000011.png» (только с использованием логических значений) или, альтернативно, «Bitmap43.png» (используя шестнадцатеричное значение восьмибитного целого числа, представляющего этот двоичный шаблон для более короткого имени файла ).

Поскольку у вас есть 256 возможных комбинаций, вам потребуется 256 битовых карт.

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

В качестве альтернативы вы можете наложить слой между нулевым (пустым) и девятью (полностью подключенными + системный круг) растровыми изображениями в каждом квадрате. Вам просто нужно использовать прозрачные .png, чтобы вы могли объединить их вместе. Недостатком является то, что браузер может медленно рисовать каждый квадрат (особенно полностью связанные). Преимущество будет в том, что вы создаете меньше данных и загружаете их с вашего веб-сайта.

Вы бы представляли саму карту в виде таблицы и добавляли свои растровые изображения в виде ссылок на изображения в каждую ячейку по мере необходимости.

Псевдокод на карту будет:

draw_map(connection_map):
    For each grid_square in connection_map
        connection_data = connection_map[grid_square]
        filenames = bitmap_filenames_from(connection_data)
        insert_image_references_into_table(grid_square,filenames)

# For each square having one of 256 bitmaps:
bitmap_filenames_from(connection_data):
    filename="Bitmap"
    for each bit in connection_data:
      filename += bit ? "1" : 0
    return [filename,]

# For each square having zero through nine bitmaps:
bitmap_filename_from(connection_data):
    # Special case - square is empty
    if 1 not in connection_data:
        return []
    filenames=[]
    for i in 0..7:
        if connection_data[i]:
            filenames.append("Bitmap"+i)
    filenames.append("BitmapSystem");
    return filenames
0 голосов
/ 20 сентября 2008

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

Bit 0 : Has planet
Bit 1 : Has line from planet going north
Bit 2 : Has line from planet going northwest
...
Bit 8 : Has line from planet going northeast

Хорошо, теперь создайте 512 изображений. Многие языки имеют библиотеки, которые позволяют редактировать и записывать изображения на диск. Если вам нравится Ruby, попробуйте это: http://raa.ruby -lang.org / project / ruby-gd

Я не знаю, как вы планируете хранить свою структуру данных, описывающую граф планет и ссылок. матрица смежности может упростить создание карты, хотя это далеко не самое маленькое представление. Тогда довольно просто выложить html как (для сетки 2x2):

<table border="0" cellspace="0" cellpadding="0">
<tr>
<td><img src="cell_X.gif"></td>
<td><img src="cell_X.gif"></td>
</tr>
<tr>
<td><img src="cell_X.gif"></td>
<td><img src="cell_X.gif"></td>
</tr>
</table>

Конечно, замените каждый X на соответствующее число, соответствующее комбинации битов, описывающих внешний вид ячейки. Если вы используете матрицу смежности, собрать кусочки довольно просто - просто посмотрите на ячейки вокруг «текущей» ячейки.

0 голосов
/ 20 сентября 2008

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

В прошлый раз, когда я проверял, старые версии IE не поддерживали прозрачность в файлах изображений. Может кто-нибудь отредактировать это, чтобы предоставить лучшую информацию о поддержке прозрачности?

0 голосов
/ 20 сентября 2008

Лично я бы просто рендерил ссылки в игре, а графика на клетках обеспечивала только фон. Это дает вам больше гибкости, позволяет более легко увеличить число способов, которыми ячейки могут связываться друг с другом, и, как правило, более масштабируемо.

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

0 голосов
/ 20 сентября 2008

Я бы порекомендовал использовать графическую библиотеку для рисования карты. Если вы это сделаете, у вас не будет вышеуказанной проблемы, и в итоге вы получите гораздо более чистый / простой код. Некоторые параметры: SVG, Canvas и flash / flex.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...