Как получить доступ к переменным в классе Game1 из другого класса в XNA?

8

Я пытаюсь написать SpriteManagerкласс в XNA, но мне нужен доступ к Gameпеременным. Например, Game.Contentсвойство будет очень полезно при загрузке текстур и Game.GraphicsDevice.Viewportпоможет получить размер окна.

На данный момент у меня есть следующий класс:

public MainGame : DrawableGameComponent
{
    public SpriteManager<Enemy> EnemyManager { get; get; }
    public SpriteManager<Powerup> PowerupManager { get; set; }
    ...
}

Я могу думать о трех способах получения доступа к этим переменным в SpriteManagerклассе:

  1. Сделайте мой класс спрайт-менеджера производным от GameComponent. Это было бы идеально, за исключением того, что мой менеджер спрайтов используется в MainGame, который является GameComponent.

  2. Используйте ((Game) Game1)для доступа к переменным. Однако, выполнение этого вида уродства ужасно и нарушает инкапсуляцию.

  3. Передайте все от MainGame. Например, EnemyManagerнеобходимо загрузить случайный противник типа каждый раз , когда он порождает противника, поэтому вместо загрузки текстур в MainGame, передать EnemyManagerв Game.Contentсобственность и позволить ей обрабатывать текстуры нагрузку. Однако я не уверен, что это лучший способ справиться с ситуацией. Я не могу положить на нее палец, но в некотором смысле это кажется «неправильным».

Я мог бы воспользоваться некоторыми советами о лучшем способе достижения этого.

Даниэль Т.
источник

Ответы:

3

Не делайте этого - вместо этого сделайте диспетчер спрайтов сервисом .

BlueRaja - Дэнни Пфлугхофт
источник
Спасибо, это первый раз, когда я услышал об игровых сервисах. Это похоже на внедрение зависимостей, но я только немного знаком с этим.
Даниэль Т.
@Daniel: Инъекция зависимостей и сервисные контейнеры - это два типа инверсии управления . Смотрите этот ответ для более подробной информации.
BlueRaja - Дэнни Пфлюгофт
1
Все так быстро делают это игровым сервисом. Это не так плохо, чтобы сделать это публичным. У вас есть только 1 игровой экземпляр ..
Сетерон
2

На самом деле # 2 не так уж и плох (я предполагаю, что вы хотели понизить с Gameдо Game1). Вы можете установить тип Game1в вашем конструкторе следующим образом:

public MainGame : DrawableGameComponent
{
    public MainGame(Game1 game) : base(game) { }
}

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

public Game1 Game1 { get { return (Game1)Game; } }

Или, если вы хотите быть предельно анальным по поводу отсутствия кастинга (а в этом нет необходимости ), вы можете сделать это:

public MainGame : DrawableGameComponent
{
    public MainGame(Game1 game) : base(game) { this.Game1 = game; }

    public Game1 Game1 { get; private set; }
}
Эндрю Рассел
источник