多线程是提高程序效率的有效手段,在游戏中也十分的常用。
1.在游戏开始时加载资源时,多线程是非常常用的。主界面显示等待的画面,多线程中这时进行资源的加载(地图资源, 地图上的对象资源。。)
2.在正常的渲染逻辑中,如果把游戏的更新在多线程中运行,游戏的效率将有很大幅度的提升。
我们将多线程封装成一个类,方面使用。
class CXMultThread
{
public:
CXMultThread(void){mHandle = NULL , mThreadID = 0;};
~CXMultThread(void){if(mHandle)CloseHandle(mHandle);};
public:
HANDLE mHandle;
DWORD mThreadID;
bool Create(LPTHREAD_START_ROUTINE MainFunc, LPVOID lpParam, bool RunWhenCreate); //第二个参数为,多线程函数的参数,第三个参数为创建后是否执行,true为执行,false为挂起
void Suspend();
void Resume();
void Terminate();
};
XMultThread.cpp:
bool CXMultThread::Create( LPTHREAD_START_ROUTINE MainFunc, LPVOID lpParam, bool RunWhenCreate )
{
if(RunWhenCreate)
{
mHandle = CreateThread(NULL, NULL, MainFunc, NULL, 0, &mThreadID);
}else
{
mHandle = CreateThread(NULL, NULL, MainFunc, NULL, CREATE_SUSPENDED, &mThreadID);
}
if(mHandle)
{
return true;
}else
{
return false;
}
}
void CXMultThread::Suspend()
{
if(mHandle)
{
SuspendThread(mHandle);
}
}
void CXMultThread::Resume()
{
if(mHandle)
{
ResumeThread(mHandle);
}
}
void CXMultThread::Terminate()
{
if(mHandle)
{
TerminateThread(mHandle ,1);
}
if(mHandle)
{
ExitThread(0); //退出当前线程,在哪个线程中执行的,哪个就是当前线程
}
}
在主函数中调用
CXMultThread MT_Load;
MT_Load.Create(&Load, NULL, true);
Load函数为加载资源的回调函数
DWORD WINAPI Load(LPVOID pParam)
{
CoInitialize(NULL);
D3DXCreateSprite(gDX->GetDVC(),&gSprite);
D3DXCreateFont(gDX->GetDVC(),32,0,0,0,0,GB2312_CHARSET,0,0,0,"宋体",&gFont);
D3DXCreateFont(gDX->GetDVC(),24,0,0,0,0,GB2312_CHARSET,0,0,0,"宋体",&gFont24);
D3DXCreateFont(gDX->GetDVC(),18,0,0,0,0,GB2312_CHARSET,0,0,0,"宋体",&gFont18);
//Sleep(3000);
gEye.Create(NULL,gDX);
gEye.mXPos.mPos=Vector(0,100,0);
gSea.Create(NULL,gDX);
gSea.AddQuakePoint(2000,2000,5,3.5);
gSea.AddQuakePoint(-670,-200,4,2.5);
gSea.AddQuakePoint(2000,0,8,4);
gSea.AddQuakePoint(0,0,2,0.5);
gMapCell.Create(NULL,gDX);
gMapCell.mXPos.mPos = Vector(100, 0 ,-100);
gSky.Create(NULL,gDX,".\\RES\\Sky\\Sky1.x");
gSky.mXPos.mZoom=Vector(0.3,0.3,0.3);
gSky.mXPos.mPos=Vector(0,-300,0);
gBox.Create(NULL, gDX, "RES\\BOX\\box.x","001.jpg,002.jpg,003.jpg,004.jpg,005.jpg,006.jpg");
gBox.mXPos.mPos=Vector(100,30,100);
gBox.mXPos.mZoom = Vector(10, 10, 10);
gBox.mXPos.mBodyPass = Vector(0, 0.5, 0);
gBox.ForceOnMap(&gMapCell, 0, uwmMap);
gCoord.Create(&gBox,gDX,201,10);
gCoord.mXPos.mPos=Vector(0,0,0);
gGS.ChangeScense(gsGame);
CoUninitialize();
return 1;
}
首先进入Loading界面,随后在多线程中加载资源。
在渲染的更新函数中:
MT_Update.Create(&UpdateMT, NULL, false);
DWORD WINAPI UpdateMT(LPVOID lpParam)
{
while(1)
{
gDX->UpdateLight(gCurrentPass);
gSea.Update(gCurrentPass);
gBox.Update(gCurrentPass);
gMapCell.Update(gCurrentPass);
MT_Update.Suspend(); //为了保证不是一直在更新,我们每次更新后将线程挂起,在每次渲染前Resume线程.
}
return 1;
}
浙公网安备 33010602011771号