用C++实现跨平台游戏开发之Allegro引擎
要:本文重点讨论开源游戏开发库Allegro(Allegro低级游戏例程),同时涉及到一些深度技术并提供了一个简单的示例程序,帮你进一步确定它是否是适合你的开发平台。
一、 一个适于多环境的引擎
Allegro最开始被研发于八十年代后期古老的Atari ST平台上,随后被快速地移植到流行的DJGPP环境(一个在九十年代早期流行的32位的 MS-DOS 扩展程序)。此后,Allegro被移植到最为流行的Windows C++开发环境中,包括VS,MinGW,Cygwin和Borland C++。另外的支持它的平台包括Linux,BeOS,QNX,Mac OSX以及几乎任何其它带有X11库的Unix平台上。
Allegro能着色到各种类型的位图和硬件加速的环境中,例如DirectX,XWindows,SVGAlib,FreeBE/AF,CGDirectDisplay,QuickDraw,等等。Allegro并不想提供它自己的3D环境或模拟器,但是OpenGL可以被容易地集成,这是通过使用AllegroGL库-它提供了一个类似于GLUT的接口(包括扩展管理)-实现的。
二、 性能概要
在进一步使用API开发前,让我们看一下Allegro提供的总体功能:
·具体到像素级的绘图函数,包括平坦阴影,gouraud阴影,纹理贴图,z缓冲的多边形和圆绘制,填充, 贝塞尔 样条曲线,图案填充,精灵,blitting(位图复制),位图计算缩放和旋转,半透明/光效果以及比例字体支持的文本输出
·FLI/FLC(在计算机生成的动画方面,这种格式比MPEG有更高的压缩性能)动画播放器
·播放后台MIDI音乐,可达64种同时的声音效果,并能录制样本 波形 和MIDI输入(声音平台支持,包括WaveOut,DirectSound,OSS,ESD,CoreAudio和QuickTime,等等)
·容易地存取鼠标,键盘,游戏杆等设备,还支持高分辨率定时器中断,包括一个DOS版本的垂直折回中断模拟器
·读/写LZSS压缩文件的例程
·数学函数,包括定点算术,表查找和3D矢量/矩阵/四元数操作
·GUI对话框管理器和文件选择器
·内建地支持16位和 UTF-8 格式的 Unicode 字符
三、 使用引擎
使用Allegro进行开发,就象在许多其它游戏场合下一样,游戏的总体结构都包括游戏开始前的初始化,游戏循环以及游戏完成后的清理。初始化意味着既包含Allegro启动代码也包含在开始的位置实现基本地装载或生成你的游戏级别。在创建你的初始化代码时,启动Allegro基本上没有什么代价付出(见图1).
如果你需要很多屏幕相关的真实性能,建议你首先礼貌地用get_gfx_mode_list()函数查询一下最大可用方式:
#include <allegro.h> //必须放于系统头文件的引用之后 set_color_depth(32); // 缺省情况下使用8位颜色 if (set_gfx_mode(GFX_AUTODETECT, 640, 480, 0, 0) != 0) { abort_on_error("Couldn’t set a 32 bit color resolution"); } |
set_gfx_mode()的最后两个参数用于指定虚拟缓冲区的大小-我们的图形屏幕存储于其中。这可以使创建一个卷边游戏-其中地形是连续移动的-变得容易。例如,你可能要使虚拟缓冲区,比方说,宽出20%以留出足够的空间来平滑卷动新的精灵和地形。
四、 一个完整的Allegro实例
本教程将使用Kee-Yip Chan的SnookerClone演示程序,它是基于James Lohr的另一个具有相同名字的演示程序。图1显示了演示程序的基本屏幕快照。
![]() 图1.Kee-Yip Chan的"SnookerClone"演示程序 |
这个工程向你展示了许多不同的Allegro技术,包括动画,键盘输入和鼠标输入,碰撞和游戏物理知识(例如重力)。它利用了三个主要的元素:一个有8个扶手的旋转的车轮,一个用箭头键来控制的大红球,还有一些从顶部往下坠落的蓝球。车轮以接触方式推动红球,而当红球碰上蓝球时,它们之间相互影响。
下列是完整的Allegro演示程序的代码:
1 #include <allegro.h> 2 vector<Point> g_points; //aka球上点的列表 3 vector<Joint> g_joints; //物理对象列表,如车轮和缓冲器 4 kVec g_accControl; 6 int main(void) 7 { 8 allegro_init(); // 初始化allegro. 9 install_keyboard(); // 启动键盘. 10 install_mouse(); // 启动鼠标. 11 install_timer(); //过程show_mouse()所需要; 13 // 创建一个800x600的非全屏窗口. 14 set_gfx_mode(GFX_AUTODETECT_WINDOWED, 800, 600, 0, 0); 16 set_window_title("Kee-Yip Chan’s Snooker Clone"); 17 text_mode(-1); // 文本将被画在透明的背景之上 19 BITMAP* buffer = create_bitmap(SCREEN_W, SCREEN_H); //创建一张位图用于双缓冲. 21 // 初始化数据. 22 create_joints(g_joints); //注册车轮、地板和缓冲器的硬编码的屏幕位置 25 // 创建顶点以组成aka球: 玩家所用球和三个蓝球 26 // 的位置, 速度, 大小和质量. 27 g_points.push_back(Point(kVec(100, 300),kVec(0, 0),16, 10)); // 玩家. 28 g_points.push_back(Point(kVec(50, 40), kVec(0, 0),12, 5)); // 中等的球. 29 g_points.push_back(Point(kVec(80, 40), kVec(0, 0) 12, 5)); //中等的球. 30 g_points.push_back(Point(kVec(110, 40),kVec(0, 0),6, 1)); // 小球. 32 //主循环,在按ESC键后退出 33 while(!key[KEY_ESC]) { //检查输入. 34 if(key[KEY_UP]) 35 g_accControl.y = -0.07; //Jet pack.向上加速 36 if(key[KEY_LEFT]) 37 g_accControl.x = -0.07; //左走.向左加速 38 if(key[KEY_RIGHT]) 39 g_accControl.x = 0.07; //右走.向右加速 41 static bool leftMousePressed = false, rightMousePressed = false; 42 if(mouse_b & 1) { //鼠标左键按下 43 if(!leftMousePressed){ 44 leftMousePressed = true; // 创建一个新球. 45 g_points.push_back(Point(kVec(mouse_x, mouse_y),kVec(0, 0), 12, 5)); 46 } 47 } 48 if(!(mouse_b & 1)) 49 //保证不重复鼠标按键 50 //否则,就会出现许多的新球 51 leftMousePressed = false; 52 if(mouse_b & 2) { //鼠标右键按下 53 if(!rightMousePressed){ 54 rightMousePressed = true; // 创建一个新球 55 g_points.push_back(Point(kVec(mouse_x, mouse_y),kVec(0, 0), 6, 1)); 56 } 57 } 58 if(!(mouse_b & 2)) 59 //保证不重复鼠标按键 60 //否则,就会出现许多的新球. 61 rightMousePressed = false; 63 doPhysics(); 65 // 着色:如果我们能再次使用缓冲区,则清除它; //否则,旧图像将滞留显示 66 //用白色进行清除. 67 clear_to_color(buffer, makecol(255, 255, 255)); 68 for(unsigned i = 0; i < g_points.size(); i++) { //画点. 69 //画一个实心球 70 circlefill(buffer, //画向缓冲区 71 g_points[i].position.x,g_points[i].position.y,// aka 球的中心点的位置 72 g_points[i].size, // 半径. 73 (i == 0) ? makecol(255, 0, 0) : makecol(0, 0, 255)); //红色如果是玩家;否则为蓝色 75 // 画一个轮廓球. 76 circle(buffer, //画向缓冲区 77 g_points[i].position.x,g_points[i].position.y, // aka 球的中心点的位置. 78 g_points[i].size, // 半径. 79 makecol(0, 0, 0)); //红色如果是玩家;否则为蓝色. 81 } 83 // 画接合点 84 for (unsigned i = 0; i < g_joints.size(); i++) 85 line(buffer, //画向缓冲区 86 g_joints[i].p1.x, g_joints[i].p1.y, // 点 1. 87 g_joints[i].p2.x, g_joints[i].p2.y, // 点 2. 88 makecol(0, 0, 0)); // 黑颜色. 89 ); 91 // 打印指令. 92 textout(buffer, font, "Left Mouse Button - new big ball Right Mouse Button - new small ball", 93 125, 1, makecol(0, 0, 0)); 95 textout(buffer, font, "Arrow Keys - move red ball", 96 300, 592, makecol(0, 0, 0)); 98 show_mouse(buffer); // 画鼠标光标. 100 draw_sprite(screen, buffer, 0, 0);// 把缓冲区中的数据画向屏幕. 101 } // while循环结束 103 return 0; 105 }END_OF_MAIN(); |
33-101行包括了典型的游戏编程循环模式。游戏继续进行直到玩家按下ESC键退出为止。34-39行支持同时进行的键盘输入,因为你可以按下向上和向左箭头键来获取粗略的斜向运动。
在41-61行,鼠标动作被捕获到全局变量mouse_b(用于按钮),mouse_x和mouse_y。如果你一直在使用一滚轮鼠标,你还可以使用变量mouse_z。我们对反向弹跳逻辑进行了一点硬编码以确保每次鼠标按下事件只有一个球下落。
第63行调用doPhysics(),其目的是旋转车轮的线段,更新球位置,检测球碰撞和适当地改变它们的方向矢量。这个模块(350行的数学代码)有点深入了些,但它确实是一个一流的实现,值得你深入研究。
余下的代码,65-101行,开始着色,在典型的示例程序中这属于常规实现部分。这里的着色用典型的双缓冲区技术,下一次屏幕变化被计算出来并进行脱屏绘制并在最的一毫秒进行缓冲交换(第100行)。这确保了视觉的连续性又减少了烦人的闪烁-对象看上去是随机地绘制的。在着色代码部分,对line()和circlefill()的调用是相当直接的:circlefill()以x,y,半径和填充颜色作为参数。
textout_ex()函数的功能稍强于textout()(示于92-96行),允许你指定前景和背景颜色。Allegro提供例程以直接从GRX格式.fnt文件,8x8或8x16 BIOS格式.fnt文件,位图图象以及数据文件格式中装入字体。作为选择,你能导入一种大范围的Unicode字体,这可以通过写一个.txt脚本-它为每一范围的字符指定相应的不同的源文件-来实现。如果你想要支持TrueType,那么你需要AllegroTTF或相同功能的插件。
最后,在第100行的draw_sprite()实现一个覆盖性复制新生成的位图到第14行创建的屏幕对象上。覆盖性复制意指只有非透明的颜色像素被复制。在本例中,我确信它已被退化成一个"blit"(块复制)转储。
五、 Allegro的音频
这个snooker演示程序只涉及到了一些最基本的图形和I/O函数,但是并没有用到Allegro的音频开发包。该包中的MIDI混频,音响效果和录音API,其效果达到或超过几乎每一个我所见过的专业的声音库。Allegro音频应用软件大量存在,包括WinCab-一个MP3和OGG Vorbis音乐唱片机,还有LouTronic Rhythm Box-一个鼓声生成合成器,它具有可全面融合到一起的snare鼓,低音鼓和hi hat的效果。下面我们简单地回顾Allegro音频API的一小部分。
每一个使用音频的程序都应该调用reserve_voices()来指定数字和MIDI声音驱动程序分别使用的声音的数目。接下去,你能控制这些音频轨道的混合.
你可以非常容易地象下面这样插入一个音轨:
MIDI *midFile = load_midi("myfile.mid’); play_midi(midFile, TRUE);//连续循环 |
对于更复杂的需要,你可以安装三个钩子函数之一,它们可以使你拦截MIDI玩家事件。如果被设置为非NULL,这些例程将在每次MIDI消息,元事件和系统独占的数据块中被分别调用。
Allegro的数字音频系统被设计为从最基本的配置到可高度扩展的。你能容易安装读取器和写入器来处理新的或者不同的音频文件类型, 例如:
register_sample_file_type("mp3",load_mp3,NULL);//安装MP3读取器 |
当正播放数字音频时,你可以随时编辑它。下列代码改变将在播放一个样本参数时改变该样本(用于操作循环播放的声音):
void adjust_sample(const SAMPLE *spl, int vol, int pan, int freq, int loop); |
你能改变音量,平移音频数据并清除循环标志,在下次执行到循环末尾时,这将停止该样本。如果在播放相同样本的好几个副本,这会调整它遇到的第一个副本。如果该样本没有播放,对它没有任何影响。
用C++实现跨平台游戏开发之Allegro引擎相关推荐
- 游戏开发之UDK引擎介绍和模型导入
2014-09-18 10:01:3 UnrealDevelopmentKit(虚幻引擎开发工具包).简称UDK,是一套强大并免费的游戏引擎开发套件.能够用来制作高端的3D游戏或者场景展示. 只是,假 ...
- [整理]Unity3D游戏开发之Lua
原文1:[Unity3D]Unity3D游戏开发之Lua与游戏的不解之缘(上) 各位朋友,大家好,我是秦元培,欢迎大家关注我的博客,我地博客地址是blog.csdn.net/qinyuanpei.如果 ...
- 开发中的“软”与“硬”:高画质移动游戏开发之道
摘要:游戏的效果不仅与游戏引擎的渲染相关,与硬件优化也有千丝万缕的联系.一款基于芯片优化的移动游戏界面,甚至可以堪比视频游戏的视觉效果.高通半导体事业部资深经理刘晓光从软硬件两个层面分享了移动游戏开发 ...
- DirectX游戏开发之3D角色动起(下)
DirectX游戏开发之3D角色动起(下) 直接先上图吧! 动作idle 动作attack 动作walk 动作run 看,多动作的模型搞下来了.原则上只要在此基础上略做修改就可以实现3d游戏的基本制作 ...
- 游戏开发之U3D实现技能图标冷却的效果
游戏开发之U3D实现技能图标冷却的效果 --本次使用的NGUI插件. 制作思路:NGUI插件里面有个UISprite组件,在它上面有个属性叫Type,改变相应的Type类型有不同的作用,本次使 ...
- DirectX游戏开发之2D文字的实现
DirectX游戏开发之2D文字的实现 文字是承载信息最有效的载体之一,各种游戏程序都离不开文字的显示.对于3D文字来说,2D文字有其渲染的高效性和实现的简洁性. 2D文字的显示无论在写2D游戏还是在 ...
- 游戏开发之U3D插件EasyTouch5.x使用
游戏开发之U3D插件EasyTouch5.x使用 本篇只讲EasyTouch5.x的使用,不讲源码.本来想把EasyTouch5.x的使用手册翻译一遍,想来也是没那个时间. 第一 ...
- 微信小游戏开发之CocosCreator多分辨率场景适配方案
主题 Cocos Creator不同手机分辨率的背景图像和场景内容适配 特别说明 CocosCreator微信小游戏开发系列文章,是我在逐步开发过程中,基于官方文档之上,记录一些重点内容,以及对官方文 ...
- libGDX游戏开发之Box2D(十四)
libGDX游戏开发之Box2D(十四) libGDX系列,游戏开发有unity3D巴拉巴拉的,为啥还用java开发?因为我是Java程序员emm-国内用libgdx比较少,多数情况需要去官网和goo ...
最新文章
- python学习之循环语句的九九乘法表
- Keras【Deep Learning With Python】逻辑回归·softmax多分类与交叉熵
- XnView v1.93.6 Final 注册机
- 连接查询 左连接 右连接 内连接 1112 sqlserver
- Windows系统中常见的进程DOS操作命令
- oracle数据如何导入hadoop,hadoop hive 与 Oracle 互相导入数据
- vmware虚拟机i copied it 和 i moved it的区别
- mysql 集群操作系统_mysql集群部署
- 运动目标跟踪(八)--时空上下文(STC)跟踪原理
- 【JSP教程】JSP期末考试复习要点大纲
- jdk1.8 新特性(中英文)及中文版帮助文档
- 解决 Hbuilder打包 Apk pad 无法横屏 以及 H5 直接打包 成Apk
- 【View】之【SimpleWaveView】可多色可刷新的加速球、进度球【demo】
- 最优化算法之牛顿法、高斯-牛顿法、LM算法
- 游戏手柄(JoyStick)编程学习笔记(1)
- “Stream has already been operated upon or closed” Exception in Java
- An element could not be located on the page using the given search parameters.
- vue 获取用户位置 高德_Vue使用高德地图
- 9月17日服务器维护,《海岛纪元》9月17日维护公告 「失落之城」正式开服
- python第三章_Python学习(第三章)