Я в процессе создания маленькой игры. Движок будет иметь несколько событий, на которые GUI может подписаться. События:
- ballselected
- balldeselected
- ballmoved
- ballremoved
Это было бы хорошо, если бы у меня был только один тип мяча, но есть типы шариков с Х-номером. Все они происходят от абстрактного класса Ball.
Каждый тип мяча имеет свои собственные действия, которые происходят, когда это событие происходит для них. Все они должны будут передавать различную информацию обратно в графический интерфейс. Например, у меня есть эти два типа шаров (здесь больше просто уменьшение количества информации).
- BallBouncing
- BallExploding
BallBouncing должен сообщить GUI, куда он мог переместиться, поэтому просто передал бы информацию о себе самостоятельно.
Взрыв шара с другой стороны уничтожил бы окружающие шары из него. Так что нужно будет сказать, какой это шар и все шары, которые он уничтожил.
эти два типа шаров могут быть запущены из одного и того же события, но иметь разные аргументы события. Я мог бы включить словарь значений, но это не так явно, как наличие пользовательских аргументов событий для каждого типа.
Я также подумал, что, если бы я создал пользовательские аргументы событий, в которых был задействован мяч, а затем унаследован от этого для каждого типа мяча, я мог бы отбрасывать аргументы событий обратно.
public abstract class BallBaseEventArgs : EventArgs
{
public Ball ball;
}
public class BallExplodingEventArgs : BallBaseEventArgs
{
public IList<Ball> explodedBalls;
}
Таким образом, в обработчике событий GUI он будет разыгрывать аргументы событий, зная, какой тип шара используется. Мне тоже не очень нравится это решение, так как оно кажется грязным и слишком тесно связанным.
Итак, я спрашиваю, есть ли у кого-нибудь предложения, идеи, как справиться с такой ситуацией, пожалуйста.
Спасибо
Jon
EDIT
Хорошо, поэтому я подумал, что попытаюсь объяснить мою структуру немного подробнее, чтобы уточнить и посмотреть, куда нас это приведет:
У меня есть Objects DLL, которая имеет интерфейсы для доски и шара, у нее есть два Enum, один для типов доски и один для типов шара (это используется в основном для заводов, чтобы знать, какой тип объекта создавать) , DLL также имеет различные реализации класса Ball и класса Board.
абстрактный класс Ball содержит информацию, такую как цвет, его координаты X и Y, выбран BallType Enum. У него есть несколько методов, Clone () (из ICloneable) и CompareTo (с битами Equals и значением хеш-значения).
У меня есть библиотека Instance Manager DLL, в которой есть одноэлементный объект, который контролирует доступ к доске шара и данным конфигурации игры. Эта DLL также содержит BallFactory и boardFactory (не уверен, что они должны были быть в DLL-библиотеке объектов, потому что они не таковы, потому что они не являются объектами, так сказать, не уверен, что это хорошая практика).
Тогда у меня есть Engine Engine. Это касается всей логики игры. Как создаются доска и мячи, почему они создаются и как они используются. Для классов Ball и Board существует LogicFactory (все эти фабрики используют перечисления BallTypes и BoardTypes для определения, какую реализацию использовать).
Классы логики определяют, как доска перемещает шары и вызывает методы действия шара:
- ballselected
- balldeselected
- ballmoved
- ballremoved
Который из класса Ball Logic.
Причина, по которой я не поместил всю логику в сами объекты, состоит в том, что я думал, что логика и функциональность должны быть отделены от объектов, которые просто хранят данные о нем (это может быть совершенно неправильно). Большая часть функциональности относительно того, как Ball может двигаться / действовать, содержится в басовом классе BallLogic, и каждый производный класс принимает решение о том, что он вызывает (все методы являются виртуальными, поэтому при необходимости их можно изменить).
Спасибо за ваш вклад, он действительно признателен. Я делаю это для развлечения, но в основном для изучения правильных (и неправильных) способов разработки различных видов приложений.