平常开发DirectX游戏基本是用SDK或者MFC,关于两者的开发想必大家都有了很多的了解,但是基于ActiveX控件的DirectX游戏开发网上并不多见,近日有兴趣研究了一下,小有成果,不敢独享,小附文章,希望能起到抛砖引玉的功效。
我选用WIN2K+VC6+DirectX8作为开发平台,首先创建MFC ActiveX ControlWizard,假设工程名为DIG(因为在做一个名为Digger的游戏,故取此名)。编写ActiveX控件要求资源必须释放完全,要不他会给你各种各样的麻烦,错误提示框叮叮咚咚响,会让你感到这个世界都暗了,因此一定要注意资源的管理,实际上C++要求程序员对资源的管理本省就是很高的,算我多言了。
完成了这些步骤后,在初始化DirectX时我遇到了一个困难,无法取得HWND,没有这个怎么初始化D3D设备呢,在各个类中搜索了半天,终于在隐秘的地方发现了这个句柄,在OnDraw函数中的CDC* pdc可以间接得到这个句柄,pdc->GetWindow()->m_hWnd(#add 不佳,dlg直接有m_hWnd成员)。
得到句柄后初始化DirectX设备,这里我选择了ID3DXSprite作为图形显示接口,它功能强大,操作简单,支持缩放、半透明、旋转等。因为MFC对Windows消息进行了封装,不能简单使用SDK那套消息处理程序(就是有消息处理消息,没消息渲染图形)。如果直接在OnDraw函数中执行渲染函数,编译后在ActiveX Control Text Container测试是可以发现,整个程序处于运行状态,但不能对ActiveX进行大小调节,并且对于ActiveX Control Text Container的所有操作都是极端滞后的,这样开发出来的ActiveX控件是没有意义的,所以对执行渲染的那个函数单独开一个线程是个不错的选择,用CreateThread函数创建线程,事实证明这种做法所得到的FPS还是很客观的,完全能满足在网页上直接插入ActiveX控件进行游戏,测试网页上的效果也是很容易的,打开FrontPage插入ActiveX控件,不需要一句代码就完全兼容,想象一下,这是不是很令人兴奋,从理论上说绝大部分基于DirectX的小游戏都可以做成ActiveX控件,其他的我没有试验,各位可以各自试验一下,有新的发现不要忘了告诉我gogoplayer@163.com,以下是相关的源代码,仅供参考。
HINSTANCE g_hInst; //实例
HWND g_hWnd; //句柄
CSSInput g_threadInput; //输入设备
HANDLE g_hThread;
DWORD g_dwThreadID;
bool g_bIsRunning;
bool g_bIsInitialise;
CDIGCtrl::CDIGCtrl()
{
InitializeIIDs(&IID_DDIG, &IID_DDIGEvents);
g_bIsInitialise = false;
// TODO: Initialize your control's instance data here.
}
/
// CDIGCtrl::~CDIGCtrl - Destructor
CDIGCtrl::~CDIGCtrl()
{
// TODO: Cleanup your control's instance data here.
//释放
GameRelease();
}
/
// CDIGCtrl::OnDraw - Drawing function
//渲染用线程
void WINAPI ListenThread(void)
{
g_bIsRunning = true;
while (g_bIsRunning == true)
{
g_threadInput.Capture();
if (g_threadInput.IsUp(DIK_ESCAPE))
g_bIsRunning = false;
Render();
}
return;
}
void CDIGCtrl::OnDraw(
CDC* pdc, const CRect& rcBounds, const CRect& rcInvalid)
{
if (g_bIsInitialise == false)
{
g_hInst = AfxGetInstanceHandle();
g_hWnd = pdc->GetWindow()->m_hWnd;
InitGame();
g_threadInput.Create(g_hInst, g_hWnd);
g_bIsInitialise = true;
g_hThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)ListenThread, (void *)this, 0, &g_dwThreadID);
}
}
在文章的最后,我还用VB测试了这个ActiveX控件,效果很好,轻轻一划,一个窗体,一个控件,0行代码实现游戏,这感觉,爽。