对于一个开源游戏,我想重新设计资源管理系统,但是陷入了僵局,需要一些指向一些阅读材料或现在去哪里的指针。
资源格式:
我要解决的问题是凌乱的代码(没有SRP ...),资源的不统一处理以及大多数访问的dynamic_cast(基本上是dynamic_cast<type*>(Get("foo", 42))
)。仅使用一种纹理也可以简化渲染(也许是2种:一种带有播放器蒙版,一种没有播放器蒙版)
我的方法(基于ENTT):
ResourceLocator
:给定名称,返回要加载的档案列表(处理扩展名/覆盖)ResourceCache<Type>
:保存给定类型的已加载资源ResourceLoader<Type>
:加载资源ResourceRegistry
:可容纳多个缓存,1个定位符和(也许)装载程序。通过首先检查缓存并在未命中时加载它(将其添加到缓存)来提供对所有资源的访问权限这对于声音效果和音乐很有效:
SoundEffect& get(ResId id){
if(id in soundcache) return it;
archive& = get(id.name);
SoundEffect* effect = load(archive)
add to cache and return effect;
}
这很好,很通用。但是我正在努力为具有不同类型的纹理执行此操作:
Loader
存储了对地图档案的引用,而简称为GetMapTexture(idx)
->的使用者可能不是是否需要所有地图,我是否应该在更改地图时卸载所有地图并根据需要重新加载?("archive", number)
作为键不再起作用。另外可能需要组合许多纹理(例如,分割位图或带有建筑物/人物的阴影...),并且有动画。这导致fixed size multi-D-arrays具有许多不同的索引,其含义包含在Loader
类中。
因此“常规”纹理很容易:只需将它们加载到OGL纹理中并使用即可。其他的(通常)需要将多个图像组合成1个纹理。因此,我不想将这些部分放到纹理缓存中,而只将它们合并。但是拥有这些多重D阵列也感觉像是设计缺陷。我将如何引用/使用它们?别人怎么做?
注意:组成纹理/ bld ...的图像的索引可以很容易地根据国家/地区索引,建筑物索引,动画帧索引...来计算。
用法示例(来自当前/旧代码):
drawAnimal(int type, int dir, int animationFrame){animal_cache[type][dir][animationFrame].draw(pos...);}
drawCarrier(...){carrier_cache[carriedWare][dir][animationFrame][isFat].draw(pos, playerColor,...);}
drawBuilding(...){building_cache[nationIdx][bldIdx].draw(pos, playerColor,...);}