Проблема неразрешима, как и было задано. В конечном итоге вы можете создать реку, которую игрок прослеживает до вершины небольшого холма посреди пустыни.
Есть несколько альтернатив, которые могут сделать эту работу:
ЛОД и физика:
Вы можете суб- и супер-сэмплировать шум Перлина для создания карт с разными разрешениями. Если в ваших тайлах 1 тайл на 1 метр, вы можете создать всю карту на более управляемом уровне, скажем, 1 тайл на 1 км, рассчитать реалистичные точки источника и бурный путь реки, а затем разделить вниз, скажем, 1 тайл на 100 м - на этом уровне вы знаете, где река течет с точностью до 10 плиток, определяете, где река течет по этому пути, а затем рекурсивно, где река течет через эти меньшие плитки, и т. д., пока не достигнете полного уровня детализации.
Лучше заранее рассчитать это и сохранить, если это возможно. Вы по-прежнему можете запускать это по требованию, но писать код не так уж и просто.
LOD и 1D перлин
Как указано выше, на карте низкого разрешения найдите высшую точку, откуда может исходить источник, найдите ближайшую точку на уровне моря, нарисуйте прямую линию. Теперь используйте 1D-шум Перлина, чтобы сделать ветер на реке перпендикулярным линии.
Это гораздо проще кодировать — могут быть некоторые нереалистичные артефакты, но в такой 2D-игре вы вряд ли их заметите.
Подделай это
Иметь 2 стиля рек. Кто-то идет «в гору», кто-то «в гору». Создайте плитки, показывающие, как река вытекает из источника и превращается в полноводную реку, а также плитку, показывающую полноводную реку, впадающую в небольшой подземный объект.
Если значение шума Перлина для прибрежной зоны является очень точным значением, то это порождает реку «в гору». Это перемещается к самой высокой точке края плитки, которая не граничит с исследованной плиткой, а затем, когда загружается следующая плитка, переходит к следующей самой высокой точке. Если он обнаружит, что достиг локального максимума (нет более высокой точки) или все соседние плитки уже исследованы, вернитесь примерно к середине, поместите плитку, на которой изображена река, выходящая из пещеры, источника или чего-то еще под землей, поэтому пользователь не видит реку, начинающуюся с вершины небольшого холма.
Если значение шума Перлина для горы является очень точным значением, то оно порождает «нисходящую» реку, следуя до самой нижней другой границы неисследованного тайла, и если оно достигает локального минимума или участка без неисследованных соседей , поместите плитку, на которой изображена река, исчезающая под землей.
Обычно этого достаточно для тайловой 2D-игры.
2 (или более) перлин-канала
В настоящее время вы запускаете генератор Perlin один раз для каждой плитки, чтобы получить одно значение. Я бы предложил запускать его несколько раз для каждой плитки (конечно, с разными исходными значениями и обычно с разными коэффициентами масштабирования). Используйте эти несколько значений для заполнения плиток вместо одного;
Это может помочь развеять представление о том, что бук находится рядом с равниной, равнина обычно находится рядом с лесом, лес обычно находится рядом с горами и т. д.
Если вы запустите его дважды — я бы предложил влажность и высоту. Если вы запустите его 3 раза, я бы предложил размер объекта (песок/камень, лед/снег или голая местность -> луг -> кустарник -> деревья), влажность (пустыня -> плодородная -> река -> болото) и высота (вода -> равнины -> холмы -> горы). 4 раза, возможно, тоже будут включать температуру.
Вместо того, чтобы сосредотачиваться на том, чтобы река текла «под гору», попробуйте пропустить ее там, где влажность находится в пределах определенного контурного диапазона. Хотя река не будет «реально» течь вниз по склону, в игре с плитками, такой как та, которую вы показываете, высота скрыта, вам лучше убедиться, что деревья растут рядом с реками, реки не граничат с пустыней, а земля возле рек плодородные сельскохозяйственные угодья.