游戏中的对象资源信息管理

首先要说明的是资源格式。资源格式一般存放如下格式

 

资源

 |

 --- part0

 |

 ----part1

 |

 ----part2

 |

 ...

 

一个很好的例子就是模型信息文件,在一个模型信息文件中,存放了整个物体的所有部分,每一个部分又是单独的信息。这样做的目的在于游戏中的换装。

还有一个例子就是特效文件,比如将一个门派的技能做为一个特效文件,而这个特效文件中包含了所有技能的技能特效。又或者说,当我们要实现不同等级的技能有不同特效的时候,就可以将一个技能做一个特效文件,而特效文件中存放的则是不同的等级的特效。

 

接下来就是要说明逻辑和渲染部分的划分。有些游戏是直接将渲染和逻辑嵌在一起的。这样做我觉得非常不好,不便于后期扩充。加上渲染部分的东西在逻辑里乱飞,也会干扰清析度。并且,你不能假设所有写逻辑的同伴都喜欢和图形沾亲带故的。因为有必要将渲染部分和逻辑划分开来。

一种常见的分法就是将渲染部分交给场景管理器,而由场景管理器引出一个场景对象。好比Ogre中的Entity 这个Entity是挂接在场景切点上的。 在这个Entity中,就包含了我们需要显示和绘制的东西,如模型,特效,位置,材质等等东西。逻辑在使用的时候,只需让逻辑对象派生(Class导出方式),或者嵌入(导出接口方式)这个场景对象,即可实现信息的共享。我采用的是接口导出方式。

 

class ISceneObject;

class CGameObject

{

...

  ISceneObject *mSceneObject;

};

 

划分情况就是如此了。那我们如何与场景对象接口通信呢。场景对象接口需要提供一些什么操作呢? 那些改变基础属性的,

 

如位置,方向,大小,移动,控制动画等都是很直观的。 那我们如何改变一个场景对象的渲染信息? 改变这些渲染信息的时候,又应该以什么样的方式来进行?

在此我们想到,逻辑中,一个对象都有他自身的各种属性,如果这个对象需要被渲染,肯定也需要一些渲染信息,如采用什么哪些模型的part,模型上有哪些特效等。 直接的方案就是按照上面讲的资源划分方式提供如下信息表。

struct SRenderInfo

{

  TCHAR[64] szResFile;//存储信息的文件名

  TCHAR[64] szResName;//信息文件中的资源名

};

 

那么,当我们想要为场景中的一个人物增加一件装备的时候,我们就可以像这样提供一个接口。ISceneObject::AddPart(const

 

TCHAR* modelInfoFile,const TCHAR* partName)=0;

 

而假设现在我有一个“肩膀”,肩膀是“天尊套装”中的“肩膀”。那么这个装备的SRenderInfo mRenderInfo结构的值是{_TEXT("天尊套装"),_TEXT("肩膀")} 我们调用mSceneObject->AddPart(mRenderInfo->szResFile,mRenderInfo->szResName);便可以修改一个模型的肩膀,外部并不用关心这个模型的任何渲染过程。

 

那我们要增加一个特效呢? 要知道,特效是随时都在调用的,当你释放一个技能的时候,特效被增加,当你技能放完了,特效又会被删除。 (有个例外的情况就是光环类技能,这种技能的特效是会随着技能的关闭才删除的)。 总的来说,我们就需要ISceneObject::AddEffect(const TCHAR* effectFile,const TCHAR* effectName)=0;接口。

 

那我们或许会想做些优化,比如当我穿戴同样的装备的时候,就可以不用再调用AddPart了。嗯,或许你会说这种东西用不着优化,那好吧。那特效呢? 成十成百的人放特效的时候,如果他们都总是按着一个技能不停的放。你觉得会不会有必要呢?

 

减少了特效的切换,减少了许多API的调用,模型不用重新计算他的特效信息,不需要重新挂接。 或许,可以用字符串比较的方式来断定。比如们可以在AddEffect内部检查是不是已经有相同的特效存在了,是不是在同一位置。。这样我们就可以不用做更多的工作。当然,这样是可以的。 而外部呢,你有信息在字符串乱飞的同时保证所有东西都正确吗?

其实上面的解释都不足以让我搬出下面的东西,但是有时候它会让程序写着简单。

想像一下,在配置文件中, 我们总是会给资源一个索引,然后才是他真正的内容。我们很少看到一个东西用字符串来索引的,当然,也有,我没有说没有。我们是不是可以试着将所有信息存放起来,然后用一个索引来索引它们呢? 比如现在有50个玩家出现在你的周围,而他们穿的装备中有50%是共同的,如果我们采用刚刚的方式,就会出现许多个sizeof(TCHAR)*64*2.并且,装备模版,特效模版的信息

 

如果没有和他们放一起,会是多么复杂的一件事。 但是,如果通过索引的话,仅仅是一个16位索引,就可以解决问题。其实我们一开始就可以这样做,除了模型显示信息外,还有一些基础信息都是共同的,这就是我们经常提到的装备模版。 当我们采用索引后,一切就变得简单了。 用索引索引出这些信息,再传给场景对象,看起来多么容易的一件事啊。

 

其实我现在不是这样做的,我是在场景管理内部做了一个资源信息表,这个表不管其它的,只负责资源ID,资源文件和资源部分的对应关系。 而场景管理是不会加载任何的资源信息的。 因为我根本不知道一个游戏的资源配置文件会写成什么样,会用什么写(XML INIEXCEL?)。于是,对外提供了一个注册这些资源信息到内部的接口。而当我们上面的接口则变成了

ISceneObject::AddPart(int resId);

ISceneObject::AddEffect(int resId);

看到了吗? 我并没有用modelId,effectId.说明什么呢,说明所有资源采用的是统一编号。 这样做貌似不太好。但这样在场景管理中就不再需要维护多种资源的资源表了。而上面这两个函数的实现,则是根据资源索引取得资源信息,然后就可以正式进行操作了。

 

或许,我们可以把这个映射交给写逻辑的人处理,只是不知道他们愿不愿意。

之所以写出来,是因为我在犹豫,到底哪种方案更好,或者有没有更好的方案来解决这个事情。。。。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值