我正在 C++11 中使用一些 SDL2 示例,并且正在考虑为我的游戏构建一个ResourceManager
。此类将负责管理所有资源(加载、卸载、渲染等(。在我看来,它的工作原理是这样的:
ResourceManager manager = ResourceManager();
manager.addSprite("player", "sprites/player.png");
manager.addAudio("background", "music/song.mp3");
Sprite player = manager.get("player");
player.render(0, 0);
Audio background = manager.get("background");
background.play();
我计划将资源存储在 ResourceManager 类内的数组中。这是一个好的做法吗?有没有更好的使用 SDL 资源的方法?
有各种不同的方法可以做到这一点。您应该考虑使用某种哈希表,将键(字符串名称(与对象相关联。这个想法更像是一个定位器,而不是管理器,因为管理器意味着它控制对象的生存期。研究XNA的ContentManager是如何工作的,以获得一个非常好的资源管理API的例子。显然,这是 C#,但 API 非常干净友好。
所以我的建议是,对于基本资源位置,你应该使用无序地图。如果您想添加更多功能,例如生命周期管理或内容加载,则可以将其包装。
根据您的示例,您可以包装哈希集并添加您自己的模板化 Load 方法,其工作原理如下:
template <typename Type>
Type* ResourceManager::Load( char* name, char* filePath )
{
Type* t = new Type( );
t->Initialize( name, filePath ); // this implies that anything
// to be added to your manager
// will be required to have an Initialize
// method with this signature.
_resources[ name ] = t; // _resources is your hash_map<char*, void*>;
return t;
}
这显然是资源管理的一个粗略示例,但总的来说,关于这个主题还有很多东西需要学习。我建议阅读一般的数据结构(如链表和二叉树(,然后研究工厂、单例和生成器等设计模式。这些只是起点,但足以为你指出这类事情的正确方向。祝你好运!
在实现细节上,不,避免数组。STL具有适当的容器,这些容器使用起来同样高效且更安全。特别是,map
s 和 unordered_map
s 将精确地执行名称和资源之间的映射。
关于总体设计,我强烈建议你研究一下现有框架的作用。 OGRE 3D有一个很好的实现,为游戏量身定制的资源管理类。特别是,它包括预加载资源的功能,因此您不会因按需加载资源而变慢。您还可以指定"内存预算",以便可以自动卸载资源。