APP下载

基于C语言的跨平台2D游戏框架设计

2021-08-19苏雄张宏桥段凌飞曾晓华

现代计算机 2021年21期
关键词:实例绘制精灵

苏雄,张宏桥,段凌飞,曾晓华

(湘南学院电子信息与电气工程学院,郴州423000)

0 引言

C语言是较为底层的高级语言,由于其标准简单规范,在多个领域均较为流行[1-2]。出于教学目的,大部分学生在学习完C语言后,不能进一步探究,对基本的数据结构与算法感觉枯燥。为解决这个问题,目前已有部分高校以游戏引擎等与现实紧密结合的内容为导向,提升学生的编程语言学习兴趣[3-5]。以此为出发点,本文使用跨平台的C语言库SDL2实现了一套2D游戏框架CSimpleEngine来激发学生进一步的学习研究的兴趣。该框架使用C语言(C99标准)实现,依赖于SDL2开源库,该库支持音视频、网络等功能的操作,且支持跨平台编译[6]。对于跨平台部分,本文使用C4Droid作为跨平台编译器,使用的版本为C4Droid v6.97汉化版,其本身已经集成好GCC以及SDL2库,方便本文设计框架的APK编译。此外,文中所涉及的CSimpleEngine框架与演示工程代码已开源提交到https://gitee.com/suiwobian/csimple-engine.git。

1 框架设计

1.1 框架模块

框架目前包含通用功能、事件编辑、输入控制、声音管理、精灵管理、文字绘制、物体管理七个模块。其中,通用功能模块主要负责常用算法的实现,如平面旋转、碰撞位置检测等通用功能;事件编辑模块负责用户层逻辑,包括物体事件声明、定义注册,是用户层设计的主要工具,出于代码复用目的,用户使用该模块的宏进行操作;输入控制模块负责用户层的输入检测,如鼠标或屏幕的点击、键盘按键状态等信息的获取;声音管理模块负责音效资源的配置与使用,包含音乐与音效两种类型。精灵管理模块负责图片载入以及纹理资源显示;文字绘制模块负责字体文件的载入并利用精灵管理模块对字体纹理进行显示。

其中,物体管理模块是整个框架的核心,用户主要通过操作实例完成逻辑。此外,物体与实例的区别在于:前者指某一类对象的模板抽象,后者指动态实例化的可以操作的物体。各模块的关系如图1所示。

图1 框架功能模块

1.2 执行流程

CSimpleEngine框架基于SDL2开源库,主要分为初始化、执行、销毁这三个阶段。

初始化阶段流程如下图所示:首先调用SDL_Init函数进行SDL库的初始化,包含初始化音频和视频功能,使用TTF_Init进行字体功能初始化,并根据配置创建全局窗口绘制表面以及渲染器。接着调用用户实现的资源注册接口,该接口对资源文件与配置文件中定义的资源枚举量进行关联,然后调用用户定义的物体初始化接口,该接口主要负责物体事件的注册,以及其它自定义的初始化工作。其中,资源注册接口函数As⁃setInit与物体注册接口函数ObjectInit只提供接口声明,具体实现必须由用户定义,否则无法通过编译。

图2 框架初始化流程

初始化完成后,框架进入执行流程的事件轮询状态,直至用户关闭窗口或强制退出。首先处理用户输入、退出消息等内容。然后按配置帧率来执行各个物体实例事件,事件类型包含创建事件、更新事件、绘制事件、销毁事件。创建或销毁事件由用户在调用创建或销毁物体实例的相关的函数时触发回调;更新与绘制事件默认情况下由框架通过轮询模式执行,更新事件主要负责执行逻辑,绘制事件主要负责实例显示,所有物体实例更新完毕后再进行所有实例的绘制,绘制顺序可自定义。执行阶段单帧流程如图3所示。

图3 执行阶段的单帧流程

框架销毁阶段主要进行各类全局与注册资源的释放,如调用函数释放字体、SDL等库、释放主窗口绘制表面以及渲染器。

2 框架实现

2.1 框架配置

框架代码包含3个文件:CSimpleConfig.h为框架配置头文件;CSimpleEngine.h、CSimpleEngine.c为核心实现。其中上层应用依赖于CSimpleEngine,而CSim⁃pleEngine依赖于CSimpleConfig。CSimpleConfig.h主要定义了框架的执行环境,具体如表1所示。

表1 CSimpleConfig工程配置

其中,对于声音、精灵、字体、物体类型的配置,使用枚举与全局数组的形式进行资源管理。利用枚举的自增特性,当用户在CSimpleConfig配置文件插入自定义枚举时,用于存储数据的数组也在编译时自动增加。此外,物体的管理数组分别存放不同类型物体的第一个实例,然后通过实例内部的双向列表结构进行查找,实现物体归类与多实例检索功能。

2.2 框架核心

该部分由CSimpleEngine.h、CSimpleEngine.c两个文件构成,为用户层提供近100个API。功能按类别分为:通用功能、事件编辑、声音管理、输入控制、精灵管理、字体绘制、物体管理。其中,事件编辑与物体管理是应用层逻辑实现的主要工具,事件编辑模块主要利用了C语言中拼接宏#、可变宏参数__VAR_ARGS__等技巧实现。

精灵管理模块处理的精灵数据结构包含:绘制表面、纹理、子图个数(支持水平序列帧自动生成)、锚点位置、子图高度、子图宽度。

物体管理模块所管理的物体实例信息包含:四边形碰撞遮罩、物体位置、物体绘制深度(值越小离屏幕越近)、关联的精灵类型、精灵的子图号、精灵播放速度、精灵绘制角度(顺时针为正)、精灵水平与垂直缩放比例、精灵不透明度(取值范围0~1,0完全透明,1不透明)、物体类型、是否可见、是否活跃、是否使能、用于管理执行顺序的上一个和下一个物体对象指针、用于管理绘制顺序的上一个和下一个物体对象指针、自定义物体成员变量指针。若物体未定义绘制事件,则默认绘制实例所绑定的精灵,若定义了绘制事件则需要单独调用精灵绘制函数去显示。

各个模块的部分核心功能列举如表2所示。

表2 通用模块部分功能

表3 事件编辑模块部分功能

表4 声音管理模块部分功能

表5 输入控制模块部分功能

表6 精灵管理模块部分功能

续表

表7 物体管理模块部分功能

3 框架应用

3.1 双人弹球的设计

本节以双人弹球设计为例,简要的介绍框架的使用,其中操作部分使用键盘与鼠标进行弹板控制,具体代码见开源工程。

首先,打开配置文件CSimpleConfig.h进行环境编辑:修改资源文件路径RESOURCE_DIR为“./resource/PINGPONG/”,里边包含了弹球与弹板图片;开发时开启碰撞调试模式;修改窗口宽ROOM_WIDTH为640,高ROOM_HEIGHT为360;帧率RUN_FPS改为30;默认使用自定义绘制顺序。

然后,在精灵枚举SPRITE_TYPE的SPR_NULL与SPR_NUM之间插入新的枚举量:弹球精灵SPR_BALL、弹板精灵SPR_BOARD。在物体枚举OB⁃JECT_TYPE的OBJ_NULL与OBJ_NUM之间插入弹球OBJ_BALL、障碍OBJ_WALL、弹板OBJ_BOARD。

基本资源定义完成后,在主逻辑文件main.c的As⁃setInit接口中使用SpriteTypeReg函数注册上边定义的精灵资源,将其与资源目录下相关的图像文件进行关联:

其中,参数1为定义的资源枚举,参数2为资源文件路径,参数3为精灵子图个数,这里配置为1个,参数4为精灵旋转中心,即锚点位置,这里均配置为正中心。

接着为弹球定义创建与更新事件,事件定义宏内有默认指向当前物体实例的指针obj以及当前物体实例的参数指针args,编写逻辑代码时注意不要定义重名变量。此外,如果给物体定义成员变量后必须要定义物体的创建事件才能正常初始化。

弹球逻辑的实现过程如下:①使用DEFINE_EVENT_ARGS定义弹球的水平与垂直速度;②使用DEFINE_EVENT_CREATE定义弹球的创建事件,设置初始位置为中心,并给与随机速度;③使用DE⁃FINE_EVENT_STEP定义弹球的更新事件,每帧根据当前速度修改坐标,如果碰到墙壁则使垂直速度反向,如果碰到弹板则使水平速度反向,如果超过左右边界则进行新的一轮并重置随机位置。

弹板逻辑的实现过程如下:①使用DEFINE_EVENT_ARGS定义弹板的控制类型,1为鼠标,0为键盘光标上下键,并在创建事件中初始化为1;②在更新事件中如果让类型1的实例跟踪鼠标垂直位置,让类型0的实例响应键盘上下按键。

然后,在ObjectInit接口中使用REGISTER_EVENT_CREATE、REGISTER_EVENT_STEP注册以上定义好的事件。

接着创建各个物体的实例:使用ObjectCreate创建弹球并绑定精灵图;然后分别在屏幕上下方向的边沿外侧创建障碍墙体,无需关联精灵显示,只需使用ObjectSetMask与ObjectSetScale配置碰撞盒的大小与比例即可;最后使用ObjectCreate创建左右两个弹板,绑定精灵并使用OBJ_ARGS宏设置左边的弹板为键盘控制,右边为鼠标控制。

最后在程序入口,如main函数中,调用框架入口驱动函数EngineLoop()即可。

3.2 应用框架的编译

框架提供了默认的Makefile文件,使用gcc编译器,Windows下可以使用mingw进行编译。注意,工程编译时需要添加SDL2的相关头文件与依赖库,图4为弹球工程编译后的执行效果。

图4 双人弹球程序

此外,开源代码的project目录中附带了Flappy⁃Bird的Demo,涵盖了音效与文字等大部分的使用。为了方便,本文使用Android平台上的C4Droid进行APK的编译,本质是利用了Android开发环境下的Native⁃Activity,操作流程如下:

首先,将4个主要文件CSimpleConfig.h、CSim⁃pleEngine.h、CSimpleEngine.c、main.c以及工程相关的资源目录resource拷贝到手机上,使用C4Droid打开main.c。

然后,长按底侧编译按钮调出编译选项,选择编译多个源代码文件(简单),在文件路径中依次填入文件名,并用空格分开:CSimpleConfig.h CSimpleEngine.h CSimpleEngine.c main.c,点击确定,在主界面选择编译,若没有错误,则会提示编译成功,接着即可运行测试。

最后,生成安装包,点击右上角菜单,选择导出。导出配置应用标题(英文)、图标路径、应用资源目录,点击导出。导出后安装即可运行,编辑操作如图5所示。

图5 使用C4Droid编译FlappyBird工程

4 结语

本文首先基于SDL2对CSimpleEngine框架进行设计,扩展出通用功能、事件编辑、输入控制、声音管理、精灵管理、文字绘制、物体管理等模块,其中物体管理与事件编辑是整个框架的应用核心。然后介绍了框架的驱动流程,包含初始化、执行、销毁这三个阶段,其中执行阶段使用了事件轮询模式。接着分析了框架代码的3个核心文件:CSimpleConfig.h、CSimpleEngine.h、CSimpleEngine.c,并阐述了它们负责的主要功能。最后,使用双人弹球与FlappyBird的示例代码分别演示了框架的基本流程及其支持跨平台编译的特性,验证了框架的易用性和跨平台性,CSimpleEngine框架可以进一步作为日常C语言教学的课外扩展,提升学生对学习的兴趣。

猜你喜欢

实例绘制精灵
Painting ski maps 绘制滑雪地图
绘制童话
冬精灵
欢舞的精灵们
绘制世界地图
归来吧!精灵(连载三)
神秘的不速之客
完形填空Ⅱ
完形填空Ⅰ
俏美精灵