2D сетка вода / жидкость имитация (на платформенной плитке) - PullRequest
6 голосов
/ 23 октября 2010

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

На данный момент у меня есть текущая система: Когда водная плитка добавляется над другой водяной плиткой, она добавляет 1 к водной плитке ниже. Число указывает на давление.

Вот как это выглядит сейчас:

[0]   <- This water tile has 0 in pressure.
[1]   <- This water tile has 1 in pressure.

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

Пример:

[0]
[1][1]

А вот более крупный пример после добавления нескольких водных плиток:

[0][0]
[1][1][1][1]
[2][2][2][2][2]

Затем я делаю каждую водную плитку с давлением, равным или превышающим 1, пытаюсь переместиться влево / вправо, если есть свободное пространство, затем устанавливаю давление на 0 и проверяю, может ли она унаследовать давление вокруг себя от соседних водных плиток, если есть любые.

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

Если я уберу верхние плитки с водой из последнего примера:

[1][1][1][1]
[2][2][2][2][2] 

Тогда у нас есть верхний ряд с давлением 1, теперь там должно быть 0, а в нижнем ряду - 1.

Есть ли какая-нибудь более умная система, которую я могу реализовать, чтобы сделать это более правильным?

Ниже приведены ограничения:

Каждая плитка может проверять только плитки соседей. Плитка может иметь любую определенную функцию. Плитка может иметь любую переменную для хранения данных.

Ребята, можете ли вы придумать лучшую систему, которая работает лучше, чем у меня?

Обычный тестовый пример, который я делаю:

[]
[] should become [][]

[]
[]
[] should become [][][]

  []
[][][] should become [][][][]

Предполагается, что игра запускается некоторое время.

Любые предложения приветствуются!

Ответы [ 2 ]

0 голосов
/ 14 ноября 2015

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

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

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

0 голосов
/ 24 июля 2015

Может быть, вы могли бы забыть о давлениях (поскольку вы на самом деле не используете их в качестве давления) и просто использовать bool tryMove или что-то в этом роде.

Каждый шаг моделирования должен быть разбит на два подэтапа:

Первый цикл в тайлах:

  1. Если свободное место внизу свободно, установите для tryMove значение true, завершите эту плитку.
  2. Если плитка выше, установите для tryMove значение true, а для tryMove - false.
  3. Если какой-либо сосед пытается переместиться, установите для tryMove значение true.

Второй цикл в тайлах:

  1. Если попытка переместиться и свободное место внизу свободно, переместите плитку вниз, установите попробуйте переместить в ложь, закончить плитку.
  2. Если вы пытаетесь двигаться и можете двигаться в сторону (свободное место слева или справа) установите для соседей tryMove как false, переместите его, установите для этого tryMove значение false, завершите плитку.

Я думаю, что это должно исправить вашу проблему.

...