您的位置:首页 > 其它

游戏中虚拟文件系统的设计

2010-03-31 16:29 302 查看
本文转载自www.azure.com.cn

由于游戏中相关资源在发布的时候都需要打入包中,但是在平常内部开发和调试中又是使用的非打包的资源形式,为了让这两种方案都能在游戏中实施,必须使用条件编译来选择不同的文件输入输出的API,这样做会带来#ifdef #else 遍布游戏的每个区域,十分混乱,那么有必要设计一种虚拟文件系统的中间对象来分别代理这两种不同的操作。
基本思想就是利用多态来继承一个文件操作的接口类IVirtualFile,再用一个Manager (VirtualFileManager)来管理所有的IVirtualFile对象。





IVirtualFile 含有文件操作一些基本接口,类似read(), tell(), skip(), seek(), eof(), readLine() 等等。
CommonFile 代表对于硬盘是真实文件的操作类,
而 InPackageFile 代表对于包内的虚拟文件的操作类。
VirtualFileManager 包含了类似 open(), close(), 等接口。
还有VirtualFileManager是个单件,便于随时可以获得它。
VirtualFileManager 还有一个重要的接口,叫 registerPackage(),
它是用来注册整个虚拟文件系统所使用的文件包。
只要注册了所需要的文件包以后,如果将游戏中所有的文件API用IVirtualFile来代理的话,
那么在使用打包资源与非打包资源版本的切换上,根本不需要任何修改,即可通用。
下面我来解释为什么可以不用修改。
假设我们有这样一个目录结构,我们游戏的执行文件为Game.exe, 在GAME 目录下,如图:





如果不用虚拟文件系统的话,
如果在使用非打包的形式的话,我们要加载setting.xml
我们需要输入路径 “./SETTING/setting.xml” 来找到此文件。
但如果我们将SETTING, TEXTURE, SOUND 三个打包到一个Resource.sgp的包中后,
那么在GAME目录下只剩下两个文件, game.exe 和 Resource.sgp 干净了很多吧。
但是如果这时,我们如果不用虚拟文件系统话,我们要找到setting.xml需要怎么做呢?
应该是这样一个函数:
loadXML(“resource.sgp”, “setting/setting.xml”);
可以看到,在上面两种方式加载中切换是多么复杂,使用打包的形式还需要多说明一下在哪个包里面去找文件,这样如果要让两个方式都运作起来只能用#ifdef #else 来控制了。
当使用虚拟文件系统以后,所有加载就会统一了,
在创建虚拟文件系统后,需要注册所需要的包,这个例子里面我们只需要一个,真实的情况下肯定不止一个,所以我们在开始注册:
VirtualFileSystem::getSingleton().registerPackage(“./resource.sgp”);
这个函数是出错无害的,就算没有这个资源包,也不会出错,最多提示包找不到。
当我们没有在打包模式的情况下,那么SETTING, TEXTURE, SOUND 三个目录会在 GAME 目录下存在。
我们可以使用:
IVirtualFile* vf = VirtualFileSystem::getSingleton().open(“./SETTING/setting.xml”);
获得文件的操作权。
因为查找到硬盘上存在此文件,所以返回的 IVirtualFile 实际上是 CommonFile.
当我们使用在打包模式的情况下,已经不存在那三个目录了,只有一个Resource.sgp,
但虚拟文件系统可以延伸进包的内部,好比iso文件那样,当虚拟文件系统设计良好的话,
我们在注册完resource.sgp后,依然可以使用,
IVirtualFile* vf = VirtualFileSystem::getSingleton().open(“./SETTING/setting.xml”);
同一个操作来获得setting.xml(现在是虚拟文件)的操作权。
但现在IvirtualFile实际就是InPackageFile了。
当所有的文件API用此虚拟文件系统替换以后,即可实现打包模式和非打包模式的加载,无任何改动的切换了,由于resigterPackage是出错无害的,你在非打包模式下执行,就算没有包也不会出错,对游戏的运行没有任何的干扰。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: