2D游戏引擎Allegro 系列教程(二) Hello world!
本系列文章由sky编写,转载请注明出处。 http://blog.csdn.net/qq573011406/article/details/8172949
作者:袁全伟 邮箱: qq573011406@126.com 欢迎邮件交流编程心得
本系列教程索引:
2D游戏引擎Allegro 系列教程(一) 配置allegro开发环境
2D游戏引擎Allegro 系列教程(二) Hello world!
2D游戏引擎Allegro 系列教程(三) 加载并显示图片!
2D游戏引擎Allegro 系列教程(四) 文字渲染及显示汉字的方法
一:引子
在本章我做一个allegro的Hello world程序,其运行结果是创建一个窗口。
另外,为了方面以后的学习我写一个基本的运行框架。
先看下运行结果...
一片漆黑哈,啥都没有。不过没关系,这个仅是教大家使用allegro的第一步而已,以后还会陆续教大家显示图片,播放声音等等。
废话不说,直接进入正题
二:使用allegro的流程
Step 1:包含allegro的相关头文件
#define ALLEGRO_NO_MAGIC_MAIN
#include <Windows.h>
#include <allegro5/allegro.h>
#define ALLEGRO_NO_MAGIC_MAIN
Step 2:引用allegro的库文件
#pragma comment(lib,"allegro-5.0.7-mt-debug.lib") //链接Allegro的库
链接Allegro库的时候要与你程序的运行时库保持一致:
MT 静态多线程 Release版
MTd 静态多线程 Debug 版
MD 动态多线程 Release板
MDd 动态多线程 Debug 板
Step 3:初始化allegro环境
#define al_init() (al_install_system(ALLEGRO_VERSION_INT, atexit))
al_init()是一个宏,它用来帮我们自动完成allegro的初始化工作,可以看出它实际上调用了
bool al_install_system(int version, int (*atexit_ptr)(void (*)(void)))
version :指allegro的版本号
Step 4:初始化相关输入设备及插件(键盘、鼠标、手柄等)
bool al_install_mouse(void)
bool al_install_keyboard(void)
al_install_keyboard()用来初始化键盘设备,以便可以接收到鼠标消息和获取鼠标的状态
Step 5:创建一个display(就是一个可以绘图的窗口)
typedef struct ALLEGRO_DISPLAY ALLEGRO_DISPLAY;
表示一个打开的显示器或WINDOWS窗口
ALLEGRO_DISPLAY *al_create_display(int w, int h)
int w:指将要创建的display的宽度
al_set_window_title(display, "Hello World!!!");
Step 6:初始化事件队列(用来接收键盘,鼠标,display,以及一些自定义的消息)
typedef union ALLEGRO_EVENT ALLEGRO_EVENT;
它是一个联合体,它可以存储所有类型的内建事件数据对象
ALLEGRO_EVENT_QUEUE *al_create_event_queue(void)
上面这个函数用来创建一个空的事件队列,成功则返回该队列的地址,失败则返回NULL
Step 7:指定要接收哪些设备的消息
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事件
Step 8:进入游戏循环(处理消息,更新逻辑,画面等)
下面这些代码是我写的helloworld程序中的一部分,是一个简单的游戏循环结构
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{//如果事件队列中没有新事件则//计算事件间隔时候大于.033t_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.
目标bitmap是指,默认的绘图目标对象。
当我们创建好一个dispaly时,默认的BITMAP就是后背缓冲(backbuffer)
你可以把BITMAP想象成一块画布,所有的绘图操作都是在画布基础上进行的。后背缓冲也是这样的一块画布。
当我们的画画完时,就可以通过下面这个函数把这个画布显示在幕上。
void al_flip_display(void)
Step 9:结束游戏,释放所占用的内存
void al_destroy_display(ALLEGRO_DISPLAY *display)
可以销毁dispaly所占用的内存
void al_destroy_event_queue(ALLEGRO_EVENT_QUEUE *queue)
可以销毁事件队列所占用的内存
三:Hello world!程序的完整代码
//头文件
#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.033t_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;
}
四:小结
![](http://static.blog.csdn.net/xheditor/xheditor_emot/default/smile.gif)
![](http://static.blog.csdn.net/xheditor/xheditor_emot/default/bye.gif)
2D游戏引擎Allegro 系列教程(二) Hello world!相关推荐
- 2D游戏入门——小狐狸系列(二)处理素材
这个课程源自b站Up主M_Studio,链接:https://space.bilibili.com/370283072 这个系列都是我自己的学习笔记,以供以后查看 Session01:安装软件& ...
- Unity3d游戏引擎Windy系列教程:常见组件扫盲讲解3(Animator)
大家好,又见面了,今提来谈一谈Animator,这应该是一个非常有用的组件了,它的作用便是人物控制器,应该说是unity里面的一大亮点,当然今天不对他做非常深入的讲解,角色控制应该但做一个板块进行讲解 ...
- Unity3d游戏引擎Windy系列教程:常见组件扫盲讲解引入unity所需的脚本语言基础
既然好不容易等到周末,那么我多更几章好了,马上要进行的就是一个新的大类题目常见组件扫盲讲解系列博文,看完这个系列的博文你应该可以熟练运用Unity里面常见的组件了. 组件实现各种功能和效果,所以在un ...
- Unity3d游戏引擎Windy系列教程:地形的创建
各位读者老爷们,小的在这里说声对不起,因为临近月考,所以上周停更了,明天就是考试的日子了,本来打算今天也不更新了,但是考虑到大家对我的支持,和我那颗想要进步的心,我扔掉了手里的五年中考三年模拟,坐在了 ...
- 2D游戏入门——小狐狸系列(二十一)死亡检测场景切换
Session21:场景控制SceneManager 这节课我们来为游戏添加场景控制的效果. 死亡检测 首先设置角色死亡的效果,这里看弹幕说有用y轴坐标判断的,好像也行,但感觉用trigger来检测确 ...
- 2D游戏入门——小狐狸系列(二十)为人物添加下蹲动画
Session20:趴下效果Crouch 这节课我们来为主角添加趴下的效果 添加新的Button 打开Project Setting -> Input Manager,我们发现Unity并没有内 ...
- html5游戏制作入门系列教程(二)
今天,我们继续html5游戏制作入门系列的系列文章.今天,我们将继续基础知识(也许甚至是高级技巧的基础).我要告诉你如何具有渐变颜色填充对象,绘制文本,使用自定义的字体绘制文本,基本的动画,以及最重要 ...
- 认识AndEngine选自Android 2D游戏引擎AndEngine快速入门教程
认识AndEngine什么是AndEngine 随着Android手机.平板的盛行,Android下的游戏也不断的变得火热.而对于游戏开发有兴趣的同学们,应该也想要学习开发游戏.虽说游戏开发的引擎较多 ...
- Android 2D游戏引擎AndEngine快速入门教程
Android 2D游戏引擎AndEngine快速入门教程 介绍:AndEngine是一款知名的Android 2D游戏引擎.该引擎代码开源,并且可以免费使用.本书详细讲解如何使用AndEngine引 ...
最新文章
- 贪心算法简单实践 -- 分糖果、钱币找零、最多区间覆盖、哈夫曼编解码
- 基于DL的计算机视觉方法热度高涨,传统方法就可以偏废?
- Call指令和Ret指令讲解
- 试图加载格式不正确的程序_好程序员大数据学习路线之hive存储格式
- Use Amazon VM to try Openstack (1) (with DevStack)
- 基于三台主机部署phpwind
- OICQ登录号码清除器实现原理
- php gd libpng,libpng版本问题导致的PHP调用gd扩展出错解决方案
- ubuntu桌面模式下,鼠标右键没有新建文档,的解决方法
- (12) 基于深度时空残差网络ResNet的城市交通流预测
- 游戏常用算法:四种迷宫生成算法
- cad打开服务器上的文件很慢,cad2018启动慢怎么处理_cad2018打开很慢的解决教程
- 阿里语音识别(语音转文字)java调用全程手把手详解-适合中小学生快速上手
- Maven 配置与依赖冲突问题
- 前端EChart图表转换为图片保存到服务器路径
- [ZZ]什么是Google Urchin:了解Urchin与Google Analytics差异
- ddr走线教程_DDR3 Fly By走线精讲
- AVT工业相机Windows、Opencv开发——驱动相机(超详细)
- 深入理解空间金字塔池化(SPP,ASPP)
- PHP打开word文档