文/宋忆疆 上一期专栏, 我曾提到. N E T提供了一个特性叫做反射(Reflection),其实反射并不是.NET所独有的。在这一期专栏,我想和大家讨论一下反射这个特性,在游戏开发中的应用,以及发展前景。 在原生的C++程序中,我们通常会定义一些类,并且为这些类写一些方法、成员等。这些方法和成员,实现了某个游戏功能,或者记录某些数据。通常它的作用区域都是存在于编译器编译期。通过C++编译器,这些类、函数、变量就会变成一些实实在在的地址,执行模块也会给这些取一些只有它自己才知道意义的名字。然而,我们有时候会有这样的想法:我能不能在某种时候,调用进程里名叫“GetNpcName()”的函数,并且,还能给它传递所必须的参数,以得到这个函数的返回值呢? 显然,在原生C/C++一类的静态语言,目前是不具备这样能力的,而Python一类的解释性脚本,显然要做到这个要费一些周折,并且性能十分低下。在.NET框架下,引入了一个数据结构描述数据—元数据,在元数据里面,它记录了编译器编译过程中获得的各种信息,包括类名、函数名、函数参数、函数返回值、变量名、变量相对偏移,等等。在应用程序集加载的时候,这个元数据被加载起来,当用户需要这些数据,可以通过一些特殊接口来获得,并且处理执行。 那么拥有Reflection这个特性后,我们在游戏开发中,可以获得哪些好处提供了一个特性叫做反射(Reflection),其实反射并不是.NET所独有的。在这一期专栏,我想和大家讨论一下反射这个特性,在游戏开发中的应用,以及发展前景。 在原生的C++程序中,我们通常会定义一些类,并且为这些类写一些方法、成员等。这些方法和成员,实现了某个游戏功能,或者记录某些数据。通常它的作用区域都是存在于编译器编译期。通过C++编译器,这些类、函数、变量就会变成一些实实在在的地址,执行模块也会给这些取一些只有它自己才知道意义的名字。然而,我们有时候会有这样的想法:我能不能在某种时候,调用进程里名叫“GetNpcName()”的函数,并且,还能给它传递所必须的参数,以得到这个函数的返回值呢? 显然,在原生C/C++一类的静态语言,目前是不具备这样能力的,而Python一类的解释性脚本,显然要做到这个要费一些周折,并且性能十分低下。在.NET框架下,引入了一个数据结构描述数据—元数据,在元数据里面,它记录了编译器编译过程中获得的各种信息,包括类名、函数名、函数参数、函数返回值、变量名、变量相对偏移,等等。在应用程序集加载的时候,这个元数据被加载起来,当用户需要这些数据,可以通过一些特殊接口来获得,并且处理执行。 那么拥有Reflection这个特性后,我们在游戏开发中,可以获得哪些好处呢?这里简单介绍一些常用的应用:
  • 编辑器数据和UI的绑定。有了Reflection特性,我们可以做一个统一的规范,让编辑器界面和程序内数据结构直接映射,减少大量繁杂的关联代码。
  • 游戏对象的动态创建和初始化。在MFC一类的类库中,通常会提供一套RTTI(运行时类型信息)来做动态创建,创建和初始化参数等处理起来就不会力从心了。
  • 游戏内功能模块组合配置化。比如要做一个流程处理,某种情况下面调用某些代码工作。但是希望这个调用能灵活配置,那么可以通过一个配置文件,或者数据库字段,获得处理函数入口和参数。这样,后面的各种功能配置组合,都可以交给策划去填写配置文件或者数据库字段。
  • 类似游戏内图文排版一类需要高度灵活可配置的模块,用Relfection是一个很不错的选择,可以比较轻松面对各种调整修改。
在.NET平台,配合Reflection,还有Attribute系统。Attribute的作用,是对用户所写的代码进行一些标注。比如可以给一个类添加一个Attribute,打上一个标注,这个类是用来描述NPC行为的, 然后再给这个类成员函数标志Attribute,申明这个函数是用来处理NPC被交互的时候调用的,等等类似。 然后可以自己写程序, 搜集程序集内,所有打上这些标记的类和函数,然后统一做逻辑处理。 作者介绍: 宋忆疆,参与《碧血情天》,《傲世三国2》,《乱舞天下》等游戏研发。目前担任《流星蝴蝶剑OL》项目制作人。 《程序员》11年04期精彩内容:HTML5来临! 《程序员》杂志订阅
Logo

20年前,《新程序员》创刊时,我们的心愿是全面关注程序员成长,中国将拥有新一代世界级的程序员。20年后的今天,我们有了新的使命:助力中国IT技术人成长,成就一亿技术人!

更多推荐