我在本系列教程的第二篇,曾写过一个框架代码。后经过测试,虽然可以运行,但是确有些BUG,例如不能正确执行到game_destory()函数,从而导致内存泄漏。于是现在就抽空重新写了一个,发在这里。新的框架用了一个简单的状态机来实现。
以下是完整的代码:
//头文件
#define ALLEGRO_NO_MAGIC_MAIN
#include <Windows.h>
#include <allegro5/allegro.h>
#pragma comment(lib,"allegro-5.0.7-monolith-mt-debug.lib") //链接Allegro的库
//函数
int game_init(); //初始化游戏
int game_run(); //进入游戏循环
int game_update(); //逻辑处理函数
int game_render(); //渲染函数
int game_destory(); //释放资源
int game_msg(); //消息处理
//常量
const int WIN_WIDTH =800; //窗口宽度
const int WIN_HEIGHT =600; //窗口高度
//全局变量
ALLEGRO_DISPLAY *display; //显示设备
ALLEGRO_EVENT_QUEUE *queue; //事件队列
ALLEGRO_EVENT my_event; //事件
enum GAME_STATE{
GAME_INIT,
GAME_RUN,
GAME_DESTORY,
GAME_END
};
GAME_STATE FSM=GAME_INIT;
int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nShowCmd )
{
int error=0;
while(true){
switch(FSM){
case GAME_INIT:
error=game_init();
if(error!=0){
FSM=GAME_DESTORY;
break;
}
break;
case GAME_RUN:
game_run();
break;
case GAME_DESTORY:
game_destory();
break;
case GAME_END:
return error;
}
}
return error;
}
int game_init(){
//_/_/插件初始化_/_/_/_/_/_/_/_/_/__/_/_/_//_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
if (!al_init())return 1;
al_install_mouse();
al_install_keyboard();
display = al_create_display(WIN_WIDTH, WIN_HEIGHT);
if (!display)return 2;
al_set_window_title(display, "框架");
//初始化事件队列,接受到的消息将存储在该队列里
queue = al_create_event_queue();
//指定要接收哪个设备的消息
al_register_event_source(queue, al_get_keyboard_event_source());
al_register_event_source(queue,al_get_mouse_event_source());
al_register_event_source(queue, al_get_display_event_source(display));
//_/_/加载字体_/_/_/_/_/_/_/_/_/__/_/_/_//_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
//_/_/加载图片_/_/_/_/_/_/_/_/_/__/_/_/_//_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
//_/_/加载控件_/_/_/_/_/_/_/_/_/__/_/_/_//_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
FSM=GAME_RUN;
return 0;
}
int game_msg(){
al_wait_for_event(queue,&my_event);
if(my_event.type==ALLEGRO_EVENT_DISPLAY_CLOSE)return 98; //当窗口被关闭时
if (my_event.type == ALLEGRO_EVENT_KEY_CHAR) {
if (my_event.keyboard.keycode == ALLEGRO_KEY_ESCAPE)//当按下 ESC键时
return 98;
}
return 0;
}
int game_update(){
return 0;
}
int game_render(){
al_clear_to_color(al_map_rgb(0,0,0));
al_flip_display();
return 0;
}
int game_run(){
double t_now=0.0; //当前时刻
double t_pre=0.0;
int error=0;
if(!al_is_event_queue_empty(queue)){ //先检测事件对了中是否有新事件
error=game_msg(); //有 则先处理事件
if(error!=0 && error !=98)return error;
if(error==98){
FSM=GAME_DESTORY;
return error;
}
}else{
t_now=al_get_time();
if(t_now-t_pre>=0.033){
game_update();
game_render();
t_pre=t_now;
}else{
al_rest(0);
}
}
return 0;
}
int game_destory(){
FSM=GAME_END;
return 0;
}