最近在网上突然冒出了一款3D的网页游戏,因为它使得我对网页中一些招人诟病的问题有了新的认识,让我产生了想要研究一下的想法。
想要制作网页中的3d游戏,有这样几个技术问题是需要考虑的:
网页插件实现
用户安装插件是否有阻碍
如何在插件中绘制3d图形
如何链接服务端
美术资源如何缓存
美术资源如何更新
浏览器兼容问题
本文就是来解答这些问题中的一部分,并且给出具体的实现方案。
ActiveX插件技术
目前浏览器的插件技术还是蛮多的,不过能够流行起来的不多。之前因为浏览器插件安全的问题,导致大部分人都对插件有十分的警惕。
ActiveX是微软提供的浏览器插件技术,wiki上的介绍:/wiki/ActiveX。我实在是难以搞清楚微软这些年来提供的几个技术之间的关系,OLE、ALT等,包括现在最新的.Net也是一样。要学习微软的这套框架,光理解其中的概念都需要花费非常多的时间,加上代码复杂,远不如开源技术来的直接和清晰。
我这里使用的是VS,新建一个“MFC ActiveX控件”工程。
根据向导,它会自动帮你创建一个后缀名为OCX的插件的工程。要调试运行,需要修改下项目属性,改成“ActiveX控件测试容器”,如下图:
这是一个工具,专门用来加载ActiveX控件,每次调试打开这个界面后,还需要手工点击菜单:编辑->插入新控件,找到你创建的这个OCX插件。如果在弹出的列表里面没有你制作的这个插件,就需要重新编译下(编译的最后会重新注册一次控件,当然你也可以用regsvr32.exe或者其他工具来手工注册)。
当你插入过一次之后,记得保存一下,下次你就可以在文件菜单的最近打开里面找到你保存的这个会话。
到此为止,你就可以用MFC的那套框架随意的添加各种MFC提供的各种功能,比如窗口、消息、事件处理等等。如果你学过Direct3D或者OpenGL,那么完全有能力在这个空的MFC工程中添加上相关的代码,跑起你自己的Demo来。
整合3D引擎:IrrLicht
本文的目标是开发3D游戏,自然不可能从图形API开始写起,我找来了IrrLicht这个开源的引擎,据我所知国内已经有由这个引擎开发的成功的商业项目了,那么也就是说是比较成熟了。关于引擎的介绍你可以访问官网:/
当前你也可以整合进其他的引擎,wiki:游戏引擎列表 /wiki/%E6%B8%B8%E6%88%8F%E5%BC%95%E6%93%8E%E5%88%97%E8%A1%A8
IrrLicht引擎比较友好,编译过程中基本没遇到问题。切记,仔细的读一读文档和各个目录中的readme文件,这是程序员的一个好习惯。
我这里采用静态编译,正确编译后,在IrrLicht目录/bin/lib/下就会有对应不同编译器的目录,里面有编译好的lib文件。一般都会生成两个版本 Debug版:IrrLicht_d.lib,Release版:IrrLicht.lib。我会用不同的lib文件来编译我的不同版本的插件。
接下来再次配置插件的工程,这个很关键!在“C/C++”下面的“预处理器”属性页中,加入一个预处理器定义_IRR_STATIC_LIB_。
配置输入的静态链接库,给Debug和Release分别配置IrrLicht_d.lib和IrrLicht.lib(当然你需要在之前设置好VS的全局目录,保证这里IrrLicht.lib和IrrLicht_d.lib文件可以被找到):
然后根据IrrLicht的例子和文档,就可以在绘制控件的时候加入相关的代码,把3D图像绘制到MFC控件之中。在IrrLicht目录/Doc下面有引擎的文档,文档的第一页就有一个最短小的例子(很感叹IrrLicht的设计者,接口非常友好,而且跨平台)。
例子中的代码可以参考,但是无法用,因为这是在MFC的框架之中。MFC是消息驱动的,而一般的3D游戏都需要不断循环来推动图像的绘制。这就需要自己去解决这个绘制循环的问题。我这里参考了网上的一些方法,建立了一个死循环的线程,由这个线程来推动绘制。
在我的工程中,我创建了一个叫做GameFrame的类,用来做游戏逻辑层和外部的结合层,这样游戏逻辑就无需知道自己运行在什么环境中了。游戏逻辑层的初始化和主循环的驱动,由GameFrame类的提供。
GameFrame类的结构,请看头文件:
Init和Update这两个接口是最基本的,里面的是游戏逻辑代码。外部通过调用setDc来设置DC和窗口句柄,在setDc中触发Init函数。并且,外部通过createUpdateThread来启动绘制循环,循环调用Update,驱动游戏逻辑。
制作测试用html页面
我这里暂时没有考虑兼容性问题,只是给出了一个简单的例子。(这部分内容足够我写一篇文章了,呵呵)
可以看到主要是用了<object>这个标签,里面关键的是定义了classid,这个id的具体内容,是你的控件的全局唯一ID,VS已经帮你自动生成好了,在项目名Ctrl.CPP这个文件的&ldquo初始化类工厂和 guid&rdquo下面。
如果你的插件注册好了,那么打开IE浏览器,就可以看到你所绘制的东西。
工程文件下载:/detail/dczxd/3695095