游戏循环到游戏录制

一般的代码是这样的
while(1)
{
    if(PeekMessage(&msg))
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
    else
    {
        mainloop();
    }
}
如果有用户输入,则处理输入,没有则调用mainloop处理具体的游戏逻辑。处理消息输入的代码是这样的
switch(msg)
{
    case WM_LBUTTONDOW:
        POINT pt={lparam, lparam};
        handleLBtnDown(pt);
    ...
}
处理游戏逻辑的代码应该是这样的
void mainloop()
{
    //1,处理定时器和回调函数,这例会更新一些数据,比如动画
    handleTimer();
    //2,渲染场景,这里会生成需要渲染的数据,但是并不真正的把数据发往显卡
    render();
    //3,真正的显卡操作,会导致画面更新
    draw();
    //4,处理网络数据
    handleServerCmd();
}
简单总结,游戏引擎就是一个不断处理输入事件的机器,并输出处理的结果,同时需要记录当前的状态。
输出主要包括两个部分:画面显示和网络输出。
当前状态就是指引擎的整个内存状态。
输入部分比较复杂,包括几个部分:
1,用户鼠标键盘等的输入,这个最常见
2,定时器的输入,比如动画和指定时间的什么操作
3,随机数的输入,粒子效果中经常用到
4,网络输入,游戏逻辑的另一个重要的部分就在这里了。
其中,定时器是确定的,而其它三个是随机的。
再次总结,游戏循环可以抽象成3部分:
1,处理输入
2,执行引擎逻辑
3,渲染
其中执行引擎逻辑和渲染可以交给引擎去做,而处理输入可以交给脚本去做。但是脚本并不适合获取输入数据,可以再次抽象:
1,获取输入并缓存,这个需要在消息处理函数中缓存用户操作,而不直接处理消息
2,调用脚本处理输入,并会清空上一步骤的输入缓存
3,执行引擎逻辑
4,渲染
写了这么多,这样处理会有什么好处?缓存输入和即时处理输入有什么不同。
在unix中,把所有的输入设备都可以抽象成一个文件,这一原理同样适合于游戏引擎。
我们不关心网络数据具体来自于哪里,是真正的网络还是还是一个模拟的网络,甚至可以是一个普通的文件。
在处理鼠标时间的适合,至多有一个周期的延迟,相对网络延迟这个可以忽略不计。
这一的处理方式,我们就可以记录下任何一个输入,如果想对游戏进行录像,就可以把这些输入保存成一个文件。
录制的时候,我们在缓存输入的时候同时还保存输入到文件。
录像回放的时候,我们不从输入缓存获取数据,而是从此前保存的文件读取数据。
游戏本身就是一个状态机,输入一定,则状态就会一定,这样,我们就可以实现录像回放。
话说,cocos2d-x并没有采用这样的结构,估计作者根本没有想到录像的功能

你可能感兴趣的:(cocos2d-x)