На этой карте «материк» - это вся земля, которая может быть соединена с центром карты в четырех основных направлениях (север, юг, восток, запад - не по диагонали).
Я хотел бы обнаружить материк и заполнить в нем дыры. Я думал о трех вещах:
Поиск в каждой неводной (темной ячейке) ячейке, если она может быть подключена к центру карты с использованием алгоритма поиска пути. Слишком дорогой! Но это может работать на острова.
Материк заполнен ведром с зеленой краской. Каждая дыра окружена краской ... что теперь? Если я проверю каждую водную точку внутри материка на смежность, я удалю некоторые полуострова и другие географические объекты, отображаемые на береговой линии.
Какое-то обнаружение края, чтобы выяснить материк. Держите все, что есть внутри, заполните его водой, удалите то, что снаружи. Сложный?
Возможно, какой-нибудь опытный разработчик игр может помочь мне с этим, возможно, дав мне название какого-нибудь известного алгоритма или техники?
Ответы:
Удаление островов
Я делал подобные вещи раньше в одной из моих игр. Чтобы избавиться от внешних островов, процесс был в основном:
Удаление озер
Что касается избавления от дыр (или озер) внутри острова, вы делаете аналогичный процесс, но начинаете с углов карты и вместо этого растягиваетесь по плиткам «Вода». Это позволит вам отличить «Море» от других водных плиток, и тогда вы сможете избавиться от них так же, как раньше избавились от островов.
пример
Позвольте мне выкопать мою реализацию заливки, которая у меня где-то здесь (отказ от ответственности, я не заботился об эффективности, поэтому я уверен, что есть много более эффективных способов реализовать это):
Я использовал это в качестве первого шага, чтобы избавиться от озер в моей игре. После этого мне нужно было сделать что-то вроде:
редактировать
Добавление дополнительной информации на основе комментариев. Если ваше пространство поиска слишком велико, вы можете столкнуться с переполнением стека при использовании рекурсивной версии алгоритма. Вот ссылка на stackoverflow (каламбур предназначен :-)) на нерекурсивную версию алгоритма, использующую
Stack<T>
вместо этого (также в C #, чтобы соответствовать моему ответу, но должна быть легко адаптируемой к другим языкам, и есть другие реализации на этом ссылка тоже).источник
Измените алгоритм заполнения потока в четырех направлениях http://en.wikipedia.org/wiki/Flood_fill
источник
Это стандартная операция при обработке изображений. Вы используете двухфазную операцию.
Начните с создания копии карты. С этой карты превратите в морские пиксели все пиксели суши, которые граничат с морем. Если вы сделаете это один раз, это исключит 2x2 острова и уменьшит большие острова. Если вы сделаете это дважды, это устранит 4x4 острова и так далее.
На втором этапе вы делаете почти обратное: превращаете в пиксели земли все морские пиксели, которые граничат с землей, но только в том случае, если они были пикселями земли на исходной карте (поэтому вы сделали копию на этапе 1). Это возвращает острова в их первоначальную форму, если они не были полностью устранены в фазе 1.
источник
У меня была похожая проблема, но не в разработке игр. Я должен был найти пиксели в изображении, которые были смежны друг с другом и имели одинаковое значение (соединенные области). Я пытался использовать рекурсивное заполнение, но продолжало вызывать переполнение стека (я начинающий программист: P). Затем я попробовал этот метод http://en.wikipedia.org/wiki/Connected-component_labeling, на самом деле он был гораздо более эффективным, в любом случае для моей проблемы.
источник