本系列文章由sky编写,转载请注明出处。 http://blog.csdn.net/qq573011406/article/details/8172949
作者:袁全伟 邮箱: qq573011406@126.com 欢迎邮件交流编程心得
本系列教程索引:
2D游戏引擎Allegro 系列教程(一) 配置allegro开发环境
2D游戏引擎Allegro 系列教程(二) Hello world!
2D游戏引擎Allegro 系列教程(三) 加载并显示图片!
在本章我做一个allegro的Hello world程序,其运行结果是创建一个窗口。
另外,为了方面以后的学习我写一个基本的运行框架。
先看下运行结果...
一片漆黑哈,啥都没有。不过没关系,这个仅是教大家使用allegro的第一步而已,以后还会陆续教大家显示图片,播放声音等等。
废话不说,直接进入正题
#define ALLEGRO_NO_MAGIC_MAIN #include <Windows.h> #include <allegro5/allegro.h>
#define ALLEGRO_NO_MAGIC_MAIN
#pragma comment(lib,"allegro-5.0.7-mt-debug.lib") //链接Allegro的库链接Allegro库的时候要与你程序的运行时库保持一致:
#define al_init() (al_install_system(ALLEGRO_VERSION_INT, atexit))
bool al_install_system(int version, int (*atexit_ptr)(void (*)(void)))
bool al_install_mouse(void)
bool al_install_keyboard(void)al_install_keyboard()用来初始化键盘设备,以便可以接收到鼠标消息和获取鼠标的状态
typedef struct ALLEGRO_DISPLAY ALLEGRO_DISPLAY;表示一个打开的显示器或WINDOWS窗口
ALLEGRO_DISPLAY *al_create_display(int w, int h)
al_set_window_title(display, "Hello World!!!");
typedef union ALLEGRO_EVENT ALLEGRO_EVENT;它是一个联合体,它可以存储所有类型的内建事件数据对象
ALLEGRO_EVENT_QUEUE *al_create_event_queue(void)上面这个函数用来创建一个空的事件队列,成功则返回该队列的地址,失败则返回NULL
void al_register_event_source(ALLEGRO_EVENT_QUEUE *queue, ALLEGRO_EVENT_SOURCE *source)
al_register_event_source(queue, al_get_keyboard_event_source()); //指定接收键盘事件 al_register_event_source(queue, al_get_display_event_source(display));//指定接收display事件
int game_run(){ //下面的变量用来记录时间,单位是秒 //用以控制帧率(FPS),也就是每秒画面刷新多少帧, //这里我们设FPS为30,用1秒的时间单位/FPS //也就是0.033,也就是说,每次刷新的间隔时间不能小于0.033秒 double t_now=0.0; //当前时刻 double t_pre=0.0; int error=0; while (true) { if(!al_is_event_queue_empty(queue)){ //先检测事件对了中是否有新事件 error =game_msg(); //有则先处理事件 if(error!=0)return error; }else{ //如果事件队列中没有新事件则 //计算事件间隔时候大于.033 t_now=al_get_time(); if(t_now-t_pre>=0.033){ //如果时间间隔合适的话就 //更新一帧的游戏逻辑 error=game_frame(); //用来更新游戏逻辑 if(error!=0)return error; //刷新画面 error=game_render();//更新游戏画面 if(error!=0)return error; t_pre=t_now; }else{ //当CPU可以处理游戏逻辑的能力超过我们的需要时 //调用Sleep(0) //这个Windows API 将使当前的线程释放出自己的控制权, //这一点对Windows平台很重要,可以使游戏不至于占用全部 //的CPU,每次切换游戏的进程,都把可以用的时间片用完了 Sleep(0); } } } return 0; }
bool al_is_event_queue_empty(ALLEGRO_EVENT_QUEUE *queue)用来判断指定队列是否为空,也可以说是看看有没有新事件,或未处理的事件
int game_render(){ //用指定的颜色填充屏幕 al_clear_to_color(al_map_rgb(0,0,0)); //翻转 al_flip_display(); return0; }
void al_clear_to_color(ALLEGRO_COLOR color)
目标bitmap是指,默认的绘图目标对象。
当我们创建好一个dispaly时,默认的BITMAP就是后背缓冲(backbuffer)
你可以把BITMAP想象成一块画布,所有的绘图操作都是在画布基础上进行的。后背缓冲也是这样的一块画布。
当我们的画画完时,就可以通过下面这个函数把这个画布显示在幕上。
void al_flip_display(void)
void al_destroy_display(ALLEGRO_DISPLAY *display)
void al_destroy_event_queue(ALLEGRO_EVENT_QUEUE *queue)
//头文件 #define ALLEGRO_NO_MAGIC_MAIN #include <Windows.h> #include <allegro5/allegro.h> #pragma comment(lib,"allegro-5.0.7-mt-debug.lib") //链接Allegro的库 //////////////////////////////////////////////////////////////////////////////////////////// //函数 int game_init(); //初始化游戏 int game_run(); //进入游戏循环 int game_frame(); //逻辑处理函数 int game_render(); //渲染函数 int game_distory(); //释放资源 int game_msg(); //消息处理 //常量 const int WIN_WIDTH =800; //窗口宽度 const int WIN_HEIGHT =600; //窗口高度 //全局变量 ALLEGRO_DISPLAY *display; //显示设备 ALLEGRO_EVENT_QUEUE *queue; //事件队列 ALLEGRO_EVENT my_event; //事件 //////////////////////////////////////////////////////////////////////////////////////////// int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nShowCmd ) { int error=0; //把游戏初始化的代码写在我们的 game_init()函数里 //然后放到这里执行 //把game_init()的返回值赋给error //error如果为0的话表示一切正常,初始化成功了! //如果不为0的话,表示初始化的时候,发生了意外。 //需要立即结束程序,并返回错误码 error=game_init(); if(error!=0)return error; //初始化完成后,开始进入游戏的主循环, //在主循环里将循环执行,消息处理,逻辑处理,和渲染函数 error=game_run(); if(error!=0)return error; //游戏结束后,销毁所占用的资源 error=game_distory(); if(error!=0)return error; return 0; } int game_init(){ if (!al_init())return 1; /************************************************************************/ /* 使用al_init()来初始化Allegro系统 al_init实际上是一个宏,他实际上调用了 al_install_system(ALLEGRO_VERSION_INT,atexit) 该函数的返回值是布尔型,初始化成功则返回true,否则返回false */ /************************************************************************/ al_install_mouse(); al_install_keyboard(); /************************************************************************/ /* 初始化鼠标,和键盘设备,以便Allegro可以接收到鼠标和键盘消息 */ /************************************************************************/ //al_set_new_display_flags(ALLEGRO_FULLSCREEN);//如果取消掉本行注释就是全屏模式 display = al_create_display(WIN_WIDTH, WIN_HEIGHT); if (!display)return 2; /************************************************************************/ /*ALLEGRO_DISPALY *al_create_display(int w,int h) 创建显示设备 参数 w 为要创建的窗口的宽度 参悟 h 为窗口的高度 成功则返回一个disply的指针,否则返回NULL /************************************************************************/ //设置Windows的标题 al_set_window_title(display, "Hello World!!!"); //初始化事件队列,接受到的消息将存储在该队列里 queue = al_create_event_queue(); //指定要接收哪个设备的消息 al_register_event_source(queue, al_get_keyboard_event_source()); al_register_event_source(queue, al_get_display_event_source(display)); return 0; } int game_msg(){ al_wait_for_event(queue,&my_event); /************************************************************************/ /* 函数原型 void al_wait_for_event(ALLEGRO_EVENT_QUEUE *queue,ALLEGRO_EVENT *ret_event) 等到队列里有新事件时,将新事件的内容复制到 ret_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 99; } return 0; } int game_frame(){ return 0; } int game_render(){ //用指定的颜色填充屏幕 al_clear_to_color(al_map_rgb(0,0,0)); //翻转 al_flip_display(); return 0; } int game_run(){ //下面的变量用来记录时间,单位是秒 //用以控制帧率(FPS),也就是每秒画面刷新多少帧, //这里我们设FPS为30,用 1秒的时间单位/FPS //也就是0.033,也就是说,每次刷新的间隔时间不能小于0.033秒 double t_now=0.0; //当前时刻 double t_pre=0.0; int error=0; while (true) { if(!al_is_event_queue_empty(queue)){ //先检测事件对了中是否有新事件 error =game_msg(); //有 则先处理事件 if(error!=0)return error; }else{ //如果 事件队列中没有新事件 则 //计算事件间隔时候大于0.033 t_now=al_get_time(); if(t_now-t_pre>=0.033){ //如果时间间隔合适的话就 //更新一帧的游戏逻辑 error=game_frame(); if(error!=0)return error; //刷新画面 error=game_render(); if(error!=0)return error; t_pre=t_now; }else{ //当CPU可以处理游戏逻辑的能力超过我们的需要时 //调用Sleep(0) //这个Windows API 将使当前的线程释放出自己的控制权, //这一点对Windows平台很重要,可以使游戏不至于占用全部 //的CPU,每次切换游戏的进程,都把可以用的时间片用完了 Sleep(0); } } } return 0; } int game_distory(){ return 0; }