XNA-рисунок:использование одного пакета спрайтов во всей игре

StackOverflow https://stackoverflow.com//questions/12714720

  •  13-12-2019
  •  | 
  •  

Вопрос

Я разрабатываю игру XNA.Настало время быть осторожным с архитектурой.До сегодняшнего дня я всегда реализовал свой собственный метод рисования следующим образом:

public void Draw(SpriteBatch sb, GameTime gameTime)
{
    sb.Begin();
    // ... to draw ...
    sb.End();
}

Я копал DrawableGameComponent и увидел, что метод Draw выглядит следующим образом:

public void Draw(GameTime gameTime)
{
    // ...
}

Прежде всего, я знаю, что SpriteBatch может собирать множество текстур Text2D между началом и концом, так что их можно сортировать или рисовать с одинаковыми эффектами.

Мой вопрос касается производительности и стоимости передачи SpriteBatch.В DrawableGameComponent можно вызвать spritebatch игрового объекта, если его spritebatch является общедоступным.

Что предлагается, что делать программисту xna-game?

Спасибо за совет.

Это было полезно?

Решение

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

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

Очевидно, это означает, что вы не можете использовать предоставленный XNA. GameComponent система, и вам придется создать свою собственную альтернативу.Но это почти тривиально:На самом базовом уровне это просто список некоторого базового типа, имеющего соответствующие виртуальные методы.


Конечно, если вам необходимо использовать GameComponent - или ваша игра такая простая (например:прототип), что архитектура вас особо не волнует - тогда можно в принципе использовать любой метод, который вы предпочитаете получить SpriteBatch к вашему методу рисования.У всех есть недостатки.

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

С другой стороны, если вы бросаете архитектуру на ветер, я бы посоветовал сделать MyGame.spriteBatch поле public static.Это самый простой способ обеспечить доступ к нему где угодно.Его легко реализовать и легко очистить позже, когда/если вам понадобится.


Чтобы ответить на ваш вопрос о производительности:Все, что связано с прохождением SpriteBatch вокруг окажет практически незначительное влияние на производительность (при условии порядка вызовов Draw/Begin/End остается такой же).Не беспокойтесь об этом.

(Если ты видишь SpriteBatch whatever в коде, который представляет ссылку.Ссылка — это 32-битное значение (в 32-битной программе, которой являются все игры XNA).Это тот же размер, что и int или float.Он очень маленький и очень дешевый для раздачи/доступа/и т. д.)

Другие советы

Если вы наткнулись на этот вопрос, вы, вероятно, смотрели на хорошее и общее решение.Я бы предложил вам посмотреть на это:

https://gamedev.stackexchange.com/questions/14217/several-classes-need-to-access-The-same-data-way-should-the-data-be-declared/14232#14232

Я почувствовал необходимость исправить этот вопрос, потому что "Лучший способ - пройти его как аргумент. Все остальное запутано." просто не правильно . .

Лично я сейчас делаю таким образом в моем классе Gamebase:

    protected override void LoadContent()
    {
        // Create a new SpriteBatch, which can be used to draw textures.
        SpriteBatch = new SpriteBatch(GraphicsDevice);
        this.Services.AddService(typeof(SpriteBatch), SpriteBatch);
    }
.

Теперь, поскольку вы добавляете drawablegameComponents в методе инициализации вашего класса игры, вы сможете вызвать

    this.Game.Services.GetService(typeof(SpriteBatch))
.

Я бы сказал, что это самый чистый подход к решению проблемы.

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

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

((MyGame)this.Game).SpriteBatch.Draw(...)

Или вы можете просто иметь DrawableGameComponent создать новый SpriteBatch.В этом нет ничего плохого (насколько я когда-либо видел).Я полагаю, это зависит от того, сколько DrawableGameComponents вы будете создавать и как часто.

Также просмотрите результаты для искать DrawableGameComponent - там много хороших советов.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top