2012-07-04 3 views
1

В настоящее время я работаю в единстве, чтобы сделать несколько игр. Я использую C#. Обычно я доволен кодом в своей игре, и я знаю, как сделать его «элегантным», так сказать. Я очень хорошо разбираюсь в отдельных элементах (скажем, космический корабль в астероидах). Но я доволен своим кодом, пока не дойду до того, что один объект должен взаимодействовать с другим. После этой точки он становится спагетти кода, и я ВСЕГДА бросаю проект. Мне еще предстоит найти изящный способ обработки вещей. По-моему, я спрашивал в разных местах в Интернете, но, похоже, я продолжаю возвращаться к этому.Обработка взаимодействия между объектами

Есть ли общий метод обработки взаимодействий между объектами? все, что не чувствует себя взломанным? Эта проблема возникла снова в моем последнем проекте. Это проект Unity, 2d прокруткой. Обнаружение того, ударил ли я «шип» с моим персонажем, включает проверку тега объектов столкновений и наблюдение, является ли это «всплеск». Но тогда весь мой «смертный» код содержится внутри Игрока, а не шипа. Спайк на самом деле не что иное, как сетчатый коллайдер с тегом. и это кажется неправильным.

Итак, stackoverflow, как вы все справляетесь с этим?

+0

взглянуть на дизайн Посредник шаблон – Mithir

+1

или посмотреть на образец наблюдателя http://www.dofactory.com/Patterns/PatternObserver.aspx – JohnnBlade

+0

Я думаю, что в вопросе OP рассматриваются высокоуровневые патчи, такие как GRASP – GETah

ответ

2

Как сказал Джонн Блэйд в комментарии к вопросу, использование Observer Pattern, вероятно, является хорошим подходом к передаче изменений состояния между различными частями вашего приложения.

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

Например, если добавить следующие события к игроку:

  • BeforeMove (Coordinate oldCoordinate, Координатная newCoordinate, из BOOL canMove)
  • Переехал (Координация oldCoordinate, координация newCoordinate)
  • HealthChanged (INT newHealth)

и другие объекты в сцене могут иметь такие события, как:

  • DamagePlayer (интермедиат повреждение)
  • HealPlayer (интермедиат заживают)

Когда вы собираетесь переместить игрока, вы бы инициировать событие BeforeMoved - если ничего не отвечает canMove = false (например, закрытая дверь) , то переход разрешен. Затем вы обновляете позицию игрока и вызываете «Перемещено».

Итак, ваш Спайк может слушать игрок Перемещенных событий:

void Moved(Coordinate oldCoordinate, Coordinate newCoordinate) 
{ 
    if (newCoordinate.Intersects(this.Location)) 
    { 
    DamagePlayer(50); 
    } 
} 

Соответственно ваш игрок будет прослушивать события DamagePlayer.

void DamagePlayer(int damage) 
{ 
    this.Health -= damage; 
    HealthChanged(this.Health); 
} 

Что-то (возможно, на самом плеере) будет прослушивать события HealthChanged, и когда он достигает нуля или меньше, убивает игрока.

Используя этот шаблон, добавление новых функций, таких как обнаружение падения, относительно просто. Просто создайте новый наблюдатель перенесенного события:

void Moved(Coordinate oldCoordinate, Coordinate newCoordinate) 
{ 
    decimal deltaY = oldCoordinate.Y - newCoordinate.Y; 
    if (deltaY < -100) // If fell 100 units or more, take 10 damage per unit. 
    { 
    DamagePlayer(10 * Math.Abs(deltaY)); 
    } 
} 
3

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

  1. ли ваш анализ OOAD в Top-Down моды, начиная с вашей проблемой домена рыть вниз к диаграмме класса
  2. Всегда отделяйте приложение в слои (Утилиты, доступ к данным, бизнес-объекты, пользовательский интерфейс ...)
  3. И самое главное, реализовать GRASP patterns, чтобы гарантировать, что ваши объекты имеют правильные обязанности, взаимодействуя естественным образом и не сильно связаны.
3

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

Например, вы можете создать новый компонент типа DamageVolume или что-то в этом роде. Это сделало бы его более универсальным, и вы могли бы повторно использовать его для других вещей, которые наносят ущерб вашему игроку. Также вы можете настроить его с такими свойствами, как InstantKill, DamageType (что позволит игроку решить, как он умирает или какие эффекты играть) или DamageAmount. В случае столкновения вашего игрока, вы могли бы сделать что-то подобное, то:

var damager = collision.gameobject.GetComponent<DamageVolume>(); 
if (damager != null) { 
    if (damager.InstantKill) { 
     this.Kill(damager.DamageType); 
    } 
    else { 
     this.Damage(damager.DamageAmount, damager.DamageType); 
    } 
} 
Смежные вопросы