一切初始化工作结束后即可进入游戏循环。
void GEroot::enterGameLoop()
{
GEprintf("enter game loop\n");
while(m_run)
{
renderOneFrame();
}
}
很简单的代码吧!
再来看看renderOneFrame()的代码。
void GEroot::renderOneFrame()
{
//发送帧开始消息给注册了帧监听的对象
_fireFrameStarted();
//更新一帧画面
_updateAllRenderTargets();
//发送帧结束消息
_fireFrameEnded();
}
同样还是很简单吧!
void GEroot::_fireFrameStarted()
{
CFLitor first = m_ListenerList.begin();
CFLitor last = m_ListenerList.end();
for(;first != last ;++first)
{
(*first)->frameStarted();
}
}
void GEroot::_updateAllRenderTargets()
{
m_SceneMgr.draw();
}
帧监听纯虚类的定义:
class IFrameListener{
protected:
//注册这个对象,只有注册后才可以开始监听
IFrameListener();
//不能使用这个类对象指针来析构这个对象
~IFrameListener(){}
private:
friend class GEroot;
// 当一帧开始要渲染时,会先调用本函数
virtual void frameStarted() = 0;
// 当一帧渲染完毕后,会调用本函数
virtual void frameEnded() = 0;
};
有两个游戏框架组件使用了帧监听:
一:输入子系统
输入子系统在收到开始消息后,检测系统输入情况,
使用Win::PeerMessage 或 X11::XNextEvent
得到系统输入后,将输入消息发送给注册了输入监听的对象。
void GEinput::mousedown(int key,int x,int y)
{
CMitor first = m_MouseListenerList.begin();
CMitor last = m_MouseListenerList.end();
for(;first != last ;++first)
{
(*first)->mousedown(key,x,y);
}
}
二:略
在收到输入消息后检测是否发生了UI消息,如果有则使用类似Windows Dialog的回调函数发送给用户。
当然,用户的类对象也可以注册输入监听,
例如,游戏主逻辑部分可以设置为,在收到按键‘R’消息的时候使自己的状态进入结束状态,之后再进入开始状态,实现重新开始游戏的功能。