最后调用System_Start,程序就进入游戏循环了,不断执行消息处理、游戏逻辑、游戏渲染,直到游戏结束跳出循环。
//system.cpp
bool CALL HGE_Impl::System_Start()
{
MSG msg;
if(!hwnd) //必须创建窗口
{
_PostError("System_Start: System_Initiate wasn't called");
return false;
}
if(!procFrameFunc) {//必须指定游戏逻辑函数
_PostError("System_Start: No frame function defined");
return false;
}
bActive=true;
// MAIN LOOP 主循环
for(;;)
{
// Process window messages if not in "child mode"
// (if in "child mode" the parent application will do this for us)
if(!hwndParent) //窗口消息获取
{
if (PeekMessage(&msg,NULL,0,0,PM_REMOVE))
{
if (msg.message == WM_QUIT) break;
// TranslateMessage(&msg);
DispatchMessage(&msg);
continue;
}
}
// Check if mouse is over HGE window for Input_IsMouseOver
_UpdateMouse(); //更新鼠标信息
// If HGE window is focused or we have the "don't suspend" state - process the main loop
if(bActive || bDontSuspend) //如果窗口被激活或者设置了窗口失去焦点不挂起
{
// Ensure we have at least 1ms time step
// to not confuse user's code with 0
do { dt=timeGetTime() - t0; } while(dt < 1); //延时1ms,确保相邻两帧至少间隔1ms
// If we reached the time for the next frame 如果到了下一帧的时间
// or we just run in unlimited FPS mode, then 或者fps无限制
// do the stuff 开始执行
if(dt >= nFixedDelta) //如果间隔时间大于等于规定帧间隔时间
{
// fDeltaTime = time step in seconds returned by Timer_GetDelta
fDeltaTime=dt/1000.0f; //更新帧时间
// Cap too large time steps usually caused by lost focus to avoid jerks
//屏蔽由窗口失去焦点造成的过大的帧时间,避免混乱
if(fDeltaTime > 0.2f) //如果帧时间过大,将它改小
{
fDeltaTime = nFixedDelta ? nFixedDelta/1000.0f : 0.01f;
}
// Update time counter returned Timer_GetTime 更新运行时间
fTime += fDeltaTime;
// Store current time for the next frame 为下一帧保存当前时间
// and count FPS 计算刷新率
t0=timeGetTime();
if(t0-t0fps <= 1000) cfps++;
else
{
nFPS=cfps; cfps=0; t0fps=t0;
_UpdatePowerStatus();
}
// Do user's stuff 调用逻辑函数和渲染函数
if(procFrameFunc()) break; //如果proFrameFunc 返回true,跳出循环
if(procRenderFunc) procRenderFunc();
// If if "child mode" - return after processing single frame
//如果有父窗口,本帧结束
if(hwndParent) break;
// Clean up input events that were generated by
// WindowProc and weren't handled by user's code
//清除剩下不能被处理的输入事件
_ClearQueue();
// If we use VSYNC - we could afford a little
// sleep to lower CPU usage
// if(!bWindowed && nHGEFPS==HGEFPS_VSYNC) Sleep(1);
}
// If we have a fixed frame rate and the time
// for the next frame isn't too close, sleep a bit
//如果离下一帧还不是很近,延时一下,可以降低CPU占用
else
{
if(nFixedDelta && dt+3 < nFixedDelta) Sleep(1);
}
}
// If main loop is suspended - just sleep a bit
// (though not too much to allow instant window
// redraw if requested by OS)
//如果窗口被挂起
else Sleep(1);
}
_ClearQueue();
bActive=false;
return true;
}