上回将ejoy2d的启动过程基本看了一遍,这回该看消息循环了。
进了消息循环后,我最关心的就是WM_PAINT和WM_TIMER。写过win32消息的都知道,WM_TIMER就是定时器消息,一般在这里处理数据,然后再触发重绘WM_PAINT消息进行界面刷新。
代码很简单,基本上就是:
- 在WM_TIMER里调用ejoy2d_win_update
- 在WM_PAINT里调用update_frame
先看ejoy2d_win_update(mingw/winfw.c):
ejoy2d_game_update(G->game, 0.01f);
再看ejoy2d_game_update(lib/ejoy2dgame.c):
void
ejoy2d_game_update(struct game *G, float time) {
if (G->logic_time == 0) {
G->real_time = 1.0f/LOGIC_FRAME;
} else {
G->real_time += time;
}
while (G->logic_time < G->real_time) {
logic_frame(G->L);
G->logic_time += 1.0f/LOGIC_FRAME;
}
}
这里LOGIC_FRAME是30,说明游戏帧数是卡在1秒30帧,但这里传进来的time是0.01,也是定时器的间隔,看后面的逻辑,如果logic_time的间隔也是30帧,那这里这样写我就不明白为什么了?先跳过去再说。
跳到logic_frame里:
static void
logic_frame(lua_State *L) {
lua_pushvalue(L, UPDATE_FUNCTION);
call(L, 0, 0);
lua_settop(L, TOP_FUNCTION);
}
这里又跳回到lua中,去执行用户自定义的update函数。
看ex01.lua里的update函数,似乎只是把两个对象的frame值+1,具体不明。
接下来再看update_frame,里面代码的封装方式与ejoy2d_game_update非常相似,所以简化为调用流程:
update_frame =>
ejoy2d_win_frame =>
ejoy2d_game_drawframe =>
用户的lua脚本里的drawframe
到此就完成了一帧的绘制。
框架的基本流程看过来,感觉非常轻盈,二次开发完全可以只写lua,而不用管c,但这里我还是存在一些疑问的:
- 我简单对比了 mingw 和 posix 里的 winfw.c,内容基本上是一样的,为什么要每个平台都用这个文件对ejoy2d的核心部分再包装一层呢,而不是在winodow.c里直接调用ejoy2d?
- 上面的
ejoy2d_game_update这样写是为了什么呢?为什么不直接把定时器直接定为0.03来控制帧速,而要定为0.01?
本文详细介绍了Ejoy2D游戏框架的消息循环,特别是WM_PAINT和WM_TIMER消息的处理。通过源码阅读,揭示了游戏帧率为30帧/秒的设定,并探讨了可能的优化疑问。文章最后提出了对平台特定代码封装目的的思考,以及对帧率控制策略的疑问。
157

被折叠的 条评论
为什么被折叠?



