《TLBB-客户端加载创建场景分析--11.28完结(共13页).doc》由会员分享,可在线阅读,更多相关《TLBB-客户端加载创建场景分析--11.28完结(共13页).doc(13页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、精选优质文档-倾情为你奉上-ZBM一、 TLBB添加新地图,步驟如下:1. 在资源文件里的Server ConfigCofigInfo.ini 把变量SystemMode1 设为1 因为该变量在服务器有个判断,当SystemMode1 为0,只加载10张地图;当SystemMode1为1,就根据当前文件夹里的SceneInfo.ini里的 scenenumber 加载多少张地图。(这个步骤可以省略,当你在SceneInfo.ini,替换前十张地图的变量file)2. 记住新地图的格式在SceneInfo.ini 格式要求如下:scene0threadindex=0;驱动线程的索引name=洛阳
2、;场景名字active=1;场景是否激活file=newScene.scn;场景文件名serverId=0;此场景是由哪个服务器端程序调用的type=0; 场景类型, 如果是0,表示普通游戏场景,如果是1表示副本3. 在资源文件里的ClientConfig SceneDefine.txt根据格式 替换或者增加 (你们懂的,就像下面这样的格式)IDServerIDCityLevelNameXsizeZsizeFairyRegionBuildMiniMapBackSoundSceneMapPosXPosYNamePosXNamePosYSceneLevelNameNomalImageSetName
3、NomalImageNameHoverImageSetNameHoverImage000洛阳320320newScene.ScenenewScene.regionnewScene.wCollisionnewScene.jpg18daliscene590394590414Sign5MiniMap_Icon2LuoYang_NormalMiniMap_Icon2LuoYang_Hover下面是需要更换的格子:CityLevelNameXsizeZsizeFairyRegionBuildMiniMapBackSoundSceneMap PosX PosYNamePosX NamePosYSceneL
4、evelNameNomalImageSetNameNomalImage其中,SceneMap格式-是需要一系列像这样的-图1.0建议: 你复制其他地图的。比如daliscene4. 打开Scene里的地图文件,发现一个SCN格式的文件,里面是navmapname=newScene.navmonsterfile=newScene_monster.inipatrolpoint=newScene_patrolpoint.inigrowpointdata=newScene_growpoint.txtgrowpointsetup=newScene_growpointsetup.txteventfile=
5、newScene_area.inipetfile=newScene_pet.iniplatformfile=newScene_platform.inistallinfodata=newScene_StallInfo.stall但是 有的不能从地图编辑器生成这些文件,所以,你还得添加这些文件,怎么添加呢?从其他的地图文件(原来的),复制改下名,当然了,你也需要一个scn的文件,就像上面一样。(下面会有需要增加的文件数量) 下面是从地图编辑器生成一个新场景后,生成的文件xinchangjing.Dijkstra?xinchangjing.GridInfo地表信息 (每个点的位置,UV,法线,材质)
6、xinchangjing.Heightmap高度图xinchangjing.nav乱码xinchangjing.Region寻路方式(已经放弃,改用.path)xinchangjing.Scene 有对应的.Terrain的文件路径,环境光,静态模型,树、建筑物等xinchangjing.Terrain封装了地图的内容,里面是对一个地图所需要的内容.GridInfo、Heightmap、texture、material文件的路径xinchangjing.Wcollision碰撞, 调整人物高度(y值)xinchangjing_area.ini区域(长方形),作用?xinchangjing_gr
7、owpoint.txt?INT INT FLOAT FLOAT 什么意思xinchangjing_monster.ini地图上Object对象定义(看下面相关1)xinchangjing_patrolpoint.ini可操作台,传送门、打造台、缝纫台、工艺台xinchangjing_StallInfo.stall乱码相关1:scene里的dali_monster.iniinfomonstercount=134共有几个例子monster0第几个NPCguid=全局IDtype=193类型(还有疑问)name=崔逢九名字title=驿站老板标题,就是称谓pos_x=241.3763X坐标pos_z
8、=136.5375Y方向dir=27坐标script_id=2026关联的脚本IDrespawn_time=1000自杀换人?重新执行?多少帧渲染?group_id=-1团队IDteam_id=-1队伍IDbase_ai=3AI程度ai_file=0AI文件patrol_id=-1巡逻ID?shop0=-1关联商店0?shop1=-1关联商店1?shop2=-1关联商店2?shop3=-1关联商店3?ReputationID=-1名声?名誉?level=-1等级npc=1?camp=8阵营补充:你如果看其他的_monster.ini,会发现写的变量挺多不一样的,有的可忽略。下面是一个完整地图所
9、需要的文件,图1.1记得把你的(1.地图编译器的生成文件 + 2.对照着原本地图添加的文件)这些文件放入 资源_天龙版PublicScene里面需要增加的文件是:多了.scn文件、.jpg(?)、lightmap(光照)、pet(宠物)、_monster.preload(NPC所需要的obj文件)、.scnscnee.jpg(小地图)5. 还得在在资源文件里的Server Config DefaultChar.ini 该文件是你新生成的角色的初始内容,下面是其实场景 camp_0scene=0;起始场景pos_x=130.0;起始位置Xpos_z=130.0;起始位置Zcamp_1scene=
10、0;起始场景pos_x=130.0;起始位置Xpos_z=130.0;起始位置Z修改 2个起始场景 对应 你在第1步骤里填写的ID,例如 洛阳是0scene0threadindex=0;驱动线程的索引name=洛阳;场景名字做完这几步骤,当你进入游戏,就是一个由你自己设定的那个地图的样子了。二、 客户端代码地图加载器解析:分析:浮出水面的这样几个文件,A :ClientConfigSceneDefine.txt-突破口一B :publicscene 里相关地图的那些内容,(看上面的图1.1,完整的地图所需要文件)-突破口二C :ServerConfigSceneInfo.ini-服务器的,张师
11、傅的活,直接咔嚓顺便啰嗦几句:A SceneDefine.txt里面主要的是这些内容INTnLocalID;INTnServerID;/ - ServerID is here!INTnCityLevel;LPCSTRszName;INTnXSize;INTnZSize;LPCSTRszWXObjectName;LPCSTRszRegionFile;LPCSTR szCollisionfile;/ 建筑物行走面文件。碰撞LPCSTRszMiniMap;INTnBackSound;LPCSTR szSceneMap;INTnWroldMapPosX;INTnWroldMapPosY;/ 场景图标所
12、在得位置INTnNameWroldMapPosX;INTnNameWroldMapPosY;/ 场景名字所在得位置LPCSTRszSceneType;/ 场景得图标等级LPCSTRszCityNameNormalImageSet;/ 场景正常名字所用得图片资源LPCSTRszCityNameNormalImage;/ 场景正常名字所用得图片资源LPCSTRszCityNameHoverImageSet;/ 场景高亮名字所用得图片资源LPCSTRszCityNameHoverImage;/ 场景高亮名字所用得图片资源-图2.0题外:这些是在Client里的WXEngineDataBaseTDDB
13、C_Struct.h里一个结构类型_DBC_SCENE_DEFINE-场景定义怎么找到的呢?在Client 搜索SceneDefine.txt重要结果就是下面的这行 DBC_SCENE_DEFINE,SceneDefine.txt,这是一个另一个结构体_DATABASE_DEFINE数组里的元素。透过该行,其实程序就是用这个结构体,去解析文件。就是拿这个瓢去装水。因为该txt文件 都是一个固定格式的,刚好这个结构体对应。这样结构体就存着文件里的信息。当然了,肯定还有一个函数,封装了无论怎么样的结构体都能对对应的文件解析。重点:上面的红色LPCSTRszWXObjectName;指的地图的.Sc
14、ene文件。而.Scene文件里,重要的是就是一个.Terrain的路径,封装了.Terrain。而.Terrain文件里,重要的是 明白了吧。有.Heightmap与.GridInfo的路径,名字、大小、纹理等信息。.Heightmap,高度图,.GridInfo 则是一个记录地表信息的文件。因为是二进制的,所以看不到,不过,百度说是-每个点的位置,UV,法线,材质。就相信它吧。.Terrain文件大小等数据.GridInfo文件.Heightmap文件.region文件.WCollision文件.scene文件SceneDefine.txt结论:现在应该有一个这样的概念,.lightmap
15、文件、小地图文件等地表纹理文件-图2.1所以我们在标题一.TLBB添加新地图里,需要那些步骤,都是有凭有据的。细心的同学,会发现手动添加的.scn文件,没有在这出现。.scn唯一出现在ServerConfigSceneInfo.ini里面,这是在服务器的配置文件。先放放,相信张师傅肯定能解疑的。这些文件作用,具体参考上面和标题一.TLBB添加新地图里的 第4步骤。了解了图2.0,不难 发现,那么操作SceneDefine,就操作了整个地图所需要的内容。而且在上面也提到过,在Client里的WXEngineDataBaseTDDBC_Struct.h里与之相关的是一个结构类型_DBC_SCENE
16、_DEFINE-场景定义等于说,程序对结构体对象赋值,然后再调用结构体对象,就能调出所对应地图的所有信息了。有了一张完整地图所需要的信息,程序里又能索引到这些信息文件,那么程序又是怎么样,从这些文件获取更重要的信息,来组建程序里的地形类呢?线索入手:在代码里搜索_DBC_SCENE_DEFINE (因为这是地图文件的程序入口)在WXClientworldScene.cpp 类SceneScene类的作用:是围绕着成员变量const _DBC_SCENE_DEFINE* m_pTheDefine;通过这个场景定义结构,解析地图所需要的文件,加载重要的信息(看下面的重要函数),然后构成一个场景。注
17、意:不明白这个场景定义结构,见上面的图2.0TLBB里面,一个场景有这些内容的:A网格CZONE(用来把场景分割分成一个屏幕大小,便于管理)BRegion 用来在CZONE注册,来表示不可行走区域。(.Region文件,用来寻路)C可行走面。(.Wcollision文件,建筑的行走面,例如桥?等)D环境音效 -有音效,那肯定也有相应的管理,比如声大声小E如果是玩家城市,还得加载玩家建筑数据F地形 (.Terrain文件)GNPC资源重要函数:1. 初始化场景 - 函数VOID CScene:Initial(VOID)a) 构建网格 CZONE。注意:这里的网格,不是mesh的顶点网格,更不是地
18、形的网格。而是将整个游戏场景分割成固定大小的网格,每个网格单位为一个Zone,一个Zone的大小跟一个屏幕的大小类似。当然场景定义结构里(图2.0),INTnXSize;INTnZSize;这2个参数决定CZONE的大小。-图2.2 CLientConfig SceneDefine.txt320? 当然不会这么大。看这个函数里。m_nZoneXSize = pSceneDefine-nXSize / SIZE_OF_ZONE;而且在头文件定义,enum SIZE_OF_ZONE = 10 ;/Zone的大小故洛阳、苏州、大理的场景就是32*32的ZONE (也是挺大的。) b) 加载Regio
19、nRegion,不可行走区域。1) 先放入到Region链表std:vectorm_theRegion; 2) 再全部都注册到CZONE上的。(RegisteAllRegion();)3) 加载.Dijkstra文件(LoadDijk();)-Dijkstra(迪杰斯特拉)算法是典型的单源最短路径算法,用于计算一个节点到其他所有节点的最短路径。主要特点是以起始点为中心向外层层扩展,直到扩展到终点为止。c) 加载可行走面 m_WalkCollisionMng.LoadCollisionTriInfoFromFile(m_pTheDefine-szCollisionfile);类成员变量CBuil
20、dingCollisionMngm_WalkCollisionMng; 在WXCLientBuilding_CollisionMng CbuildingCollisionMng.h有定义CbuildingCollisionMng,这是一个类,1.用来加载. .Wcollision文件,2.传入平面x、z坐标,得到高度。3.判断该建筑物是否有行走面4.清空数据d) 加载环境音效-这个就先放放,0e) 如果是玩家城市,还得加载玩家建筑数据- 这个好像荒废很久,我看玩家城市都没2. 进入场景 - 函数VOIDEnterScene(VOID);a) 在渲染层创建地形,加载场景文件(.scene文件)C
21、GameProcedure:s_pGfxSystem-Scene_Load(m_pTheDefine-nLocalID, m_pTheDefine-szWXObjectName);用的是对象CGameProcedure:s_pGfxSystem(图形输出系统CrenderSystem的指针)传入2个参数,分别是本地ID,和.scene文件名,到CrenderSystem的函数Scene_Load1. 卸载所有资源 2. 加载场景文件(.scene文件)m_pRenderSystem-loadSceneFromResource(&parserExpat,theSceneDefine.c_str(
22、), General);这个函数还不是最底层的函数,我一层一层往下查找定义,到最后面。WXCoreSource FilesWXSceneInfo.cppvoid SceneInfo:load(XMLParser* parser, const String& filename, const String& groupName, bool completely) -该函数的2个主要操作如下:一 加载静态模型SceneSerializer serializer;serializer.load(this, parser, filename, groupName)WxCoreSource filesWX
23、SceneSerializer.cppVoid SceneSerializer:load(Scene* scene, XMLParser* parser, const String& filename, const String& groupName)二 加载TerraingetTerrainData()-load(parser, mTerrainFilename, groupName, completely);WXCoreSource FilesTerrainData.cpp TerrainData:load(XMLParser* parser, const String& filename
24、, const String& groupName, bool loadLightmap)该函数的操作如下:a Clear old data-清空旧资源b Parse the terrain file-解析terrain文件c Setup derived fields-安装衍生字段?d Validate the terrain file -验证terrain文件e Load heightmap-加载高度图f Load gridinfo-加载地表信息gridinfo (各个顶点的位置 纹理坐标等)g Load lightmap-加载高光图说明:加载静态模型与地形的时候,都用到了String& g
25、roupName程序参数写的是“General”,如果了解Ogre,知道Ogre有个资源组管理器ResourceGroupManager,它是通过分组管理资源(看下面的补充)。在一些Ogre例子里,你能看到resources.cfg 的文件-图2.3在TLBB的WXResources.cfg里 -图2.4General 里有.obj的文件路径 也有scene地图文件的路径即在资源管理器的General组里面找到模型、地形文件,然后加载。其中类TerrainData 储存地形数据类SceneSerializer储存模型数据3. 释放未使用资源这里用到了Ogre的资源组管理器ResourceGro
26、upManager,用于释放未使用的资源。补充:资源组管理器(ResourceGroupManager)实际上是提供加载纹理(Textures)、网格(Meshes)等可重用资源的“集线器(Hub)”。使用它,你可以将你用到的资源进行分组,并且,这些资源可以根据你的需要加载或删除。资源组管理器(ResourceGroupManager)中包括了大量的资源管理器(ResourceManagers),每个资源管理器(ResourceManagers)分管某类资源,比如纹理管理器(TextureManager)、网格管理器(MeshManager)。这儿所谓的资源是指OGRE运行时需要加载的数据。
27、4. 设置LightMap5. 取得环境特效b) 预加载所有NPC资源加载的是_monster.preload(看来NPC资源在该文件。打开是一些.obj,看来这就是NPC的模型。)/*_monster.preloadstrncat(szPreLoadFile, _monster.preload, MAX_PATH);CGameProcedure:s_pGfxSystem-Scene_PreLoad(szPreLoadFile);用的是对象CGameProcedure:s_pGfxSystem(图形输出系统CrenderSystem的指针),传入参数是_monster.preload文件名到该
28、函数Scene_PreLoad。该函数是最底层的,用于在资源管理组的“General”加载_monster.preload文件。补充说下:_monster.reload文件里面的内容是:例如- dali_monster.preload:-图2.5很简单的排列方式,只要按着一行一行读,就好了。c) 播放背景音乐补充:EnterScene函数 只是预加载NPC的obj模型文件,真正摆设这些NPC位置,或者给NPC赋值(名字,阵营,等级,lua脚本关联ID等),都是在地图文件dali_monster.ini里面.结论:通过initial函数,EnterScene函数,程序就加载了一个ZONE分割的有
29、地形、静态模型(包括NPC模型)、环境音效的完整场景。这只是加载!然后,通过加载,类TerrainData 有地形数据类SceneSerializer 有模型数据-(被类SceneInfo封装)。猜测:至今为止,我们看到了 解析地图文件-加载地图文件获得地形、模型数据那创建呢?既然TLBB用到了Ogre,应该用到Ogre的场景管理器.加载的地形直接用Ogre的创建地形.加载的静态模型也直接用Ogre的scenenode挂接管理.可是封装Ogre的场景管理器究竟是哪个类呢?下面是结论与猜测为基础的 分析图。-图 2.6Scene类Initial 函数a) 构建网格 CZONE。b)加载Regio
30、nc)加载可行走面 d)加载环境音效e)如果是玩家城市,还得加载玩家建筑数据EnterScene 函数在渲染层加载地形与预加载NPC资源.调用图形渲染系统CrenderSystemScene_LoadScene_PreLoad这2个函数Ogre渲染场景Ogre:Root:getSingleton().renderOneFrame();图形渲染系统CRenderSystem-图2.7Scene_Load 加载场景Ogre资源组管理ResourceGroupManager在组“General”加载资源现在有模型数据SceneSerializer地形数据TerrainData详看上面的加载。Word
31、第7页场景定义_DBC_SCENE_DEFINE见图2.0Ogre 场景管理器SceneManager(在这创建地形与模型,暂时没发现如何创建)Scene_PreLoad 预加载场景在这里是加载NPC的OBJ文件,是利用XML来读取的,也是用Ogre资源组 在组“General” 加载资源。现状:加载场景有了,场景数据(模型数据,地形数据)也有了,那创建呢?-Ogre渲染对象是在场景管理器完成的。那现在我们的目标就是找出场景的创建,和 Ogre场景管理器。后来,我发现我忽略了一个地方。在图形渲染系统CrenderSystem 里的Scene_Load(加载场景)-该函数在Scene里的Ente
32、rScene函数调用第二步骤:加载场景文件详见上面的EnterScene(word第7页)m_pRenderSystem-loadSceneFromResource(&parserExpat, theSceneDefine.c_str(), General);WX:System* m_pRenderSystem,是一个system的指针。loadSceneFromResource定义如下:Void System:loadSceneFromResource(XMLParser* parser, const String& name, const String& groupName) _prepr
33、ocessScene();/释放资源 mSceneInfo-load(parser, name, groupName, isEditable();-加载.scene文件 -该行作用是加载了模型与地形。 _postprocessScene(); /就是在这里创建场景。_postprocessScene(); 定义如下:voidSystem:_postprocessScene(void) mBaseScale = Ogre:Math:Sqrt(getTerrainData()-mScale.x * getTerrainData()-mScale.z); / Adjust the camera to
34、 fit to current scene _adjustCamera();clearExceptionInfo(); /bakeStaticGeometries(0); / 生成terrain type info mTerrainTypeInfos-setTerrainData(mTerrainData); mTerrainTypeInfos-updateTerrainTypeInfos(); / Create render instances mSceneInfo-initialise(this); / 告诉特效系统当前场景的灯光信息 EffectManager:getSingleton(
35、).getMainSceneLight()-updateLightInfo();结论:其实Scene类的EnterScene 就创建场景了。Scene类操作着图形渲染系统CrenderSystem 调用其Scene_Load 函数图形渲染系统CrenderSystem 操作着System 调用其loadSceneFromResource函数System操作着a.TerrainData* mTerrainData; b.SceneInfo* mSceneInfo;mSceneInfo类ScneInfo 路径:WXCoreHeader FilesWXSceneInfo.h模型的加载 封装了类Sce
36、neSerializer 这个模型数据类mSceneInfo-load(parser, name, groupName, isEditable();模型的创建mSceneInfo-initialise(this);mTerrainData 类TerrainData 路径:WXCoreHeader FilesTerrainData.h地形的加载mSceneInfo-load(parser, name, groupName, isEditable();-没错,地形加载也是这函数,详见-下面加载地形加载模型-图2.8-只是这个函数操作着也是mTerrainData。地形的创建mTerrainType
37、Infos-setTerrainData(mTerrainData); mTerrainTypeInfos-updateTerrainTypeInfos();补充:类System 路径:WXCoreHeader FilesWXSystem.h是有Ogre的类型的。-图2.9System封装了Ogre的场景管理器,用来创建场景。Ogre创建场景需要添加SceneNode 等,这得涉及一些Ogre的基础。所以,我也就不分析类System的函数postprocessScene()怎么创建场景节点等。那么,任务完成了。我只知流程,要让我写,恐怕得费N多精力。除了类调用外,如何解析地图文件(XML,open流),然后把文件里的内容,封装成为一个模型类或地形类对象储存,再用一个类封装Ogre的场景管理器,对这些模型类或地形类对象进行整理,添加挂接到场景管理器里面,这也很麻烦的。-11.28ZBM专心-专注-专业