У меня немного рассол: скажем, я делаю простую, двумерную, похожую на Zelda игру. Когда сталкиваются два объекта, каждый из них должен иметь результирующее действие. Однако, когда главный герой сталкивается с чем-то, его реакция зависит исключительно от типа объекта, с которым он сталкивался. Если это монстр, он должен оправиться, если это стена, ничего не должно произойти, если это волшебная синяя коробка с лентами, он должен лечить и т.д. (Это только примеры).
Я также должен заметить, что ОБОСТЬ является частью столкновения, то есть события столкновения должны происходить как для символа AND, так и для монстра, а не только для одного или другого.
Как бы вы пишете такой код? Я могу придумать несколько невероятно неэлегантных способов, например, иметь виртуальные функции в глобальном классе WorldObject, идентифицировать атрибуты - например, функцию GetObjectType() (возвращает ints, char * s, все, что идентифицирует объект как Monster, Box или Wall), то в классах с большим количеством атрибутов, скажем, Monster, может быть больше виртуальных функций, например GetSpecies().
Однако это становится раздражающим для поддержания и приводит к большому каскадному переключателю (или If) в обработчике столкновений
MainCharacter::Handler(Object& obj)
{
switch(obj.GetType())
{
case MONSTER:
switch((*(Monster*)&obj)->GetSpecies())
{
case EVILSCARYDOG:
...
...
}
...
}
}
Там также можно использовать файлы, и файлы будут иметь такие вещи, как:
Object=Monster
Species=EvilScaryDog
Subspecies=Boss
И тогда код может извлекать атрибуты без необходимости того, чтобы виртуальные функции загромождали все. Однако это не решает проблему каскадирования If.
И ТОГДА есть возможность иметь функцию для каждого случая, например CollideWall(), CollideMonster(), CollideHealingThingy(). Это лично мое наименее любимое (хотя они все далеки от симпатичного), потому что кажется, что это очень громоздко поддерживать.
Может кто-нибудь, пожалуйста, дать представление о более элегантных решениях этой проблемы? Спасибо за любую помощь!