В настоящее время я использую книгу «Изучение LibGdx Game Developement, Second Edition» в качестве справочника во время программирования, и я наткнулся на их реализацию класса управления активами. Они реализуют его с использованием одноэлементного шаблона, с которым я действительно не располагаю опытом. На всех экранах будет только один экземпляр этого класса Manager, и он будет удален, когда игра будет закрыта. Поэтому из моего (довольно неопытного) pov я согласился бы с автором, что одноэлемент имеет смысл, так как таким образом я не должен передавать его всем классам, в которых я нуждаюсь. Однако я также слышал, что они получили немного плохая репутация, поэтому я подумал, что попрошу здесь. Имеет ли смысл использовать одноэлементный шаблон для класса управления активами в LibGdx?Создание Asset Manager singleton
ответ
статическое поле в одиночку, как
public class YourGameClass implements ApplicationListener
{
public static AssetManager assetMgr;
}
было бы гораздо проще и легче. Просто назначьте его, когда ваша игра будет готова (как в методе create
), и ссылайтесь на нее на YourGameClass.assetMgr
. Когда ваше приложение вот-вот умрет (например, в dispose
) - утилизируйте его.
Простой. Поскольку у вас есть только один экземпляр YourGameClass
, у вас не будет проблем с этим.
Если вы изучаете разработку игр libGDX, то использование одноэлементного (или иначе static
ресурсов) - это то, чего вы действительно должны избегать.
Если вы не правильно управлять и понимать жизненный цикл static
переменных (отложенную инициализацию как типичный используемый с одноплодной является хорошим примером не должным образом управлять ими), то вы могли бы в конечном итоге использование ресурсов, которые не более длительный срок действия или имеет значение, которое вы не можете ожидать. Это связано с тем, что статика может пережить ваше приложение. Конечно, вы можете обойти это, но это проблемы, с которыми вы действительно не хотите иметь дело во время обучения.
Но, что еще более важно, это хороший признак плохой структуры (объектно-ориентированный дизайн). Вам не нужно иметь доступ к ресурсам в этом множестве, чтобы оправдать одноэлемент. Обычно вам нужен только доступ к ресурсам, например. ваша реализация Screen
.
Постоянно здесь люди спрашивают, почему их текстуры повреждены, и это всегда заканчивается тем, что они пытались использовать статические ссылки или синглеты для своих активов. Но вы понимаете, как убедиться, что вы избавляетесь от всех расходных материалов и всегда загружаете новые экземпляры, когда игра снова открыта, тогда все должно быть хорошо.
Все, что реализует одноразовые, должно быть удалено, прежде чем оно выходит из сферы действия или игра закрывается. Если вы загрузили что-то с помощью AssetManager, то достаточно просто избавиться от экземпляра AssetManager, который косвенно избавится от всего, что он загрузил.
Метод вашего верхнего уровня Класс ApplicationListener - это гарантированная точка выхода вашего приложения, и вы должны убедиться, что все одноразовые вещи в любой точке вашей игры расположены к концу этого метода.
И метод create
означает, что у вас есть новый игровой экземпляр, поэтому вы не должны пытаться повторно использовать какие-либо статические ссылки на Disposables на данный момент.
Причина, по которой у многих людей возникают проблемы, заключается в том, что синглтон часто лениво загружается, поэтому при первом перезагрузке игры экземпляр менеджера ресурсов не воссоздается (поскольку приложения для Android часто остаются в живых, даже если игровая активность завершена , и поэтому статические ссылки живут).
Прежде всего, спасибо за подробный ответ. :) Я сейчас утилизирую 'AssetManager' внутри метода' dispose() 'моего основного класса Game. Я также использую [нетерпеливую инициализацию] (https://en.wikipedia.org/wiki/Singleton_pattern#Eager_initialization), поэтому экземпляр воссоздается каждый раз, когда начинается игра. Поэтому, если я не ошибаюсь, все должно быть хорошо. –
@The_Blog вы ошибаетесь и, скорее всего, придется переделать свою обработку активов в будущем. Нет ничего плохого в регулярном объекте AssetManager и передать его тем, кто в нем нуждается. Вы можете использовать 'AssetDescriptors' как' static' в вашем классе 'Asset', чтобы вы могли легко искать и получать Assets из' AssetManager', с которым вы проходите. Есть много онлайн-ресурсов, которые учат вас неправильно, но мне очень странно, что книга учит вас этому. – Madmenyo
Обратите внимание, что ожидаемая инициализация также является примером * не * правильного управления переменными 'static'. – Xoppa
Ваша книга делает опасные вещи. Я вижу, что AssetManager много используется как статический объект, но это противоречит рекомендациям в документации. В принципе, когда вы используете свое приложение, Android может сбрасывать содержимое Singleton, и вы получите черные изображения. https://github.com/libgdx/libgdx/wiki/Managing-your-assets#creating-an-assetmanager – Madmenyo
Фактически, это не содержимое одиночного тонера, которое сбрасывается, а текстуры в видеопамяти, которые поддерживает один синглтон ссылка на. Тем не менее, полученные черные изображения одинаковы. –
@Menno Gouw Я могу понять, почему синглтон - это не лучшая идея с ответами, и я сделал это обратно к нормальному объекту, который передается. Однако объект 'AssetManager' не является статическим, поэтому с этой стороны не должно быть никаких проблем, не так ли? Попытайтесь лучше понять, потому что я прочитал документацию и не сделал ее статичной из-за этого. –