Игровое программирование - связь между игровыми объектами в 2d

Недавно я пытался изо всех сил пытаться кодировать игру на С#. Я не использую XNA для этого, так как я думал, что узнаю больше, если бы закодировал игру с нуля (хотя я использую мультимедийный движок).

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

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

У меня возникли проблемы с пониманием того, как этот объект области должен быть настроен. Это была моя первая идея: каждая область имеет несколько различных структур сбора (например, квадтрит видимости, квадрат столкновения, список объектов AI и т.д.). Поэтому, если бы я должен был добавить в игру вражескую сущность, она будет помещена в квадтрит видимости, quadtree столкновений (потому что вы можете столкнуться с сущностями) и список сущностей AI. Когда область получает запрос на обновление, она сообщает каждой из этих структур обновлять себя, которые, в свою очередь, сообщают сущностям обновить себя. Все хорошо, до сих пор.

Мой вопрос: что, если этому врагу нужно общаться с другими объектами? Например, может потребоваться знать, был ли игрок в определенном диапазоне. Или это было поражено игроком. Или где все связанные объекты находятся в области (так что это может быть pathfind).

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

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

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

Спасибо за чтение.

Ответы

Ответ 1

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

Ответ 2

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

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

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

Ответ 3

Ну, один пример - настройка архитектуры клиент/сервер. Таким образом, сервер будет обрабатывать все обновления игрового мира и внутреннюю логику, и клиент будет запрашивать только сервер, если он может выполнять определенные действия. Затем сервер ответит, и клиент будет только потом рисовать и обновлять экран игры. Объекты без игрока будут делать то же самое. Единственное отличие заключается в том, что клиент контролируется человеком, а другие объекты контролируются компьютером. Это позволит вам отделить настройку игрового мира, а также события и обновления от логики сущности.

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

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

Ответ 4

Это обычно намного проще, если у вас есть объект над сущностью, выполняющей управление. (например, "мир" или "игра".) Легко видеть, какие объекты находятся в непосредственной близости от других и соответственно отправляют события и уведомления.

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

(Кроме того, почему квадрант? Для 2D rpg грубая сетка, вероятно, будет намного проще реализовать и одинаково полезна.)