XNA-рисунок:использование одного пакета спрайтов во всей игре
-
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
.Он очень маленький и очень дешевый для раздачи/доступа/и т. д.)
Другие советы
Если вы наткнулись на этот вопрос, вы, вероятно, смотрели на хорошее и общее решение.Я бы предложил вам посмотреть на это:
Я почувствовал необходимость исправить этот вопрос, потому что "Лучший способ - пройти его как аргумент. Все остальное запутано." просто не правильно . .
Лично я сейчас делаю таким образом в моем классе 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
.В этом нет ничего плохого (насколько я когда-либо видел).Я полагаю, это зависит от того, сколько DrawableGameComponent
s вы будете создавать и как часто.
Также просмотрите результаты для искать DrawableGameComponent
- там много хороших советов.