Создание многопользовательского уровня без швов?

15

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

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

Чтобы добавить эту идею и исправить проблему, я придумал следующее: иметь триггерную зону (красный квадрат на изображении), где игроки смогут увидеть «зону клона» (зеленый квадрат). В этом зеленом квадрате объекты с противоположной стороны триггерной зоны будут скопированы в соответствующую зону клонирования (это можно увидеть с помощью фигур A & B). Когда игрок достигает начальной границы «зоны клонирования», он телепортируется на другую сторону карты.

образ

В этом примере игрок 2 подумает, что он видит игрока 1, однако на самом деле он увидит его клона и наоборот.

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

KenQueso
источник
Разрешено ли игрокам двигаться назад в предыдущую область?
XiaoChuan Yu
да, туда-сюда, так что это дает своего рода эффект "хождения по миру". Подобно тому, как мир в звёздном мире
KenQueso
2
Рассматривали ли вы просто сделать мир большим кругом? или рассматриваете уровень как большой круг и переводите его на плоскую двухмерную сцену?
Nzall
Вы не можете всегда совмещать положение камеры с контролируемым игроком?
Ali1S232

Ответы:

16

Эта система со всеми этими триггерами звучит слишком сложно и подвержена ошибкам.

Вы можете обернуть позицию игрока, используя по модулю что-то вроде playerPositionX = playerPositionX % mapWidth

Таким образом , когда ваш игрок достигает сбрасывается обратно в 0.playerPosition == mapWidthplayerPosition

Это решение может быть расширено всей системой рендеринга.

Exaila
источник
1
не будет ли это проблемой закрытия игроков, видящих игроков, чья позиция сбрасывается, телепортируется прочь?
KenQueso
Как бы вы расширили это для системы рендеринга?
Микаэль Хогстрем
Вы можете иметь игрока всегда в центре камеры и иметь карту вокруг. Как карта в режиме цивилизации на земле. Другим подходом может быть рендеринг видимой части игрока по обе стороны карты.
Exaila
4
@ MikaelHögström Выполните рендеринг как обычно, но объекты, расположенные ближе к правому краю, должны отображаться второй раз слева (то есть в pos - map_width).
Марио
1
В любом месте вашего кода, где вы ищете «какой объект находится по этой координате» или «каковы координаты этого объекта», вы должны сделать это xcoord% mapWidth. Трудно сказать без вашего кода, но это, вероятно, заставит его правильно отображаться.
Жестянщик
13

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

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

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

Утомительная часть заключается в том, что все, что касается расстояния или пути, также должно поддерживать порталы. Это включает ИИ, алгоритмы прямой видимости, затухание звука и так далее.

Хорошая особенность порталов в том, что они очень мощные. Движок сборки использовал его для имитации многоуровневых уровней, несмотря на то, что он не был «настоящим» трехмерным движком. Некоторые современные движки тоже используют порталы для создания неевклидовых пространств; Portal и Antichamber являются яркими примерами в 3D.

congusbongus
источник
2
Если вы слушаете комментарии к игре портала, то часть работы порталов реализуется путем клонирования того, что видно через дыру. (но по физическим причинам, а не рендерингом)
Mooing Duck
6

Помните, что то, что вы отображаете на экране, и то, что находится в памяти, - это две совершенно разные вещи. Представьте, что у вас есть окно, которое вам нужно заполнить данными о мире. Вы заполняете окно слева направо. Пока вы анализируете свои данные, чтобы заполнить мир, если вы достигнете конца света, просто вернитесь к началу ваших данных. Использование операции по модулю идеально. Помните, что вы должны сделать это для всего . Снаряды, лучи, игроки, физика; им всем нужно обернуть свои позиции при пересечении границ мира.

Каждый игрок делится данными, но имеет свою точку зрения на данные. Их окна заполнены по-разному в зависимости от того, где они стоят в мире.

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

MichaelHouse
источник
3

Отключите рендеринг от мира, и вы сможете сделать обход и исправить рендеринг, не прибегая к каким-либо артефактам клонирования или телепортации.

Во-первых, в вашем мире у вас есть мир фиксированного размера, от 0до Width. Каждый раз, когда объект опускается ниже 0, вы оборачиваете его до конца, а каждый раз, когда объект Widthперезагружает его до начала. Это означает, что все логические объекты в вашем мире всегда находятся в пределах досягаемости 0...Width.

Во-вторых, для рендеринга вы будете делать по модулю позицию. Таким образом, левая сторона экрана - «База», а правая - «База + Размер». Итак, вы просматриваете свой мир на предмет чего-либо в этом диапазоне. Вы на самом деле будете искать диапазон по модулю, который отобразит его обратно 0...Width.

Хитрость при поиске состоит в том, чтобы вернуть положение объекта относительно Baseлевой стороны. Это преобразует в локальные координаты экрана, так что самому рендереру не нужно беспокоиться о модуле, только поиск.

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

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

эд-ка морт-ора-й
источник
1

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

Таким образом, если ваш настоящий Мир имеет ширину всего 10 единиц, игрок и игра не узнают об этом. Для игрока мир бесконечен - и если игра спросит, что находится в позиции 15 - основная функция переведет этот запрос по модулю10 и даст упаковать предмет в позицию 5.

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

Falco
источник
1

Это не совсем то же самое, но я реализовал нечто подобное в игровом джеме. В игре игроки двигались по маленькому круговому уровню, оборачиваясь, когда игрок достигал позиции «х» числа «пи». Рендеринг был легким, потому что мы просто рендерили все, а затем вращали смещенную камеру, чтобы отслеживать происходящее. Вы можете реализовать нечто подобное, как было предложено выше:

  • При рисовании проверяйте положение камеры и определяйте, что нужно рисовать, принимая во внимание положение камеры и дальность обзора.
  • В случаях, когда камера видит за «краем» карты, выберите соответствующее количество контента с другой стороны мира, чтобы рисовать за этим краем, обычно просто добавляя или вычитая ширину уровня к их положению.
  • Логика игры должна знать об этом шве и подстраиваться под него, как указано в других ответах. Особые случаи, о которых следует знать, - это столкновения, когда один объект находится на одной стороне, но сталкивается с объектом на другой стороне.
Крис
источник