2D游戏开发 - SkyGameEngine2d 引擎架构 | 目录结构 | 引擎入口点

2D游戏开发 - SkyGameEngine2d 引擎架构 | 目录结构 | 引擎入口点

  • 一、引擎架构
  • 二、引擎目录
    • 2.1 src目录介绍
  • 三、项目目录
  • 四、引擎框架入口点分析
    • 4.1 main.cpp 分析
    • 4.2 GameAppDelegate.cpp 分析


SkyGameEngine2d - 探索 简洁 易用 ,一款适合游戏入门学习的2d游戏引擎
项目地址 https://gitee.com/xfcode/SkyGameEngine2d

QQ群号:498358732
加群链接:https://jq.qq.com/?_wv=1027&k=5odSA9K
示例游戏视频链接:https://www.bilibili.com/video/av59147631/
更多文章见:SkyGameEngine2d 游戏引擎相关文章目录汇总


一、引擎架构

游戏引擎是一个比较复杂的软件系统,按照引擎系统的构成可以初略的划分为以下模块
2D游戏开发 - SkyGameEngine2d 引擎架构 | 目录结构 | 引擎入口点_第1张图片
引擎基于windwos平台,在平台之上使用了 DriectX11MIC 库。并且引入了一些第三方的库(Tinyxml2、WICTextureLoader)。

引擎中大量的使用了C++11的特性以及其标准库,其中最为重要的内存管理机制依赖于C++中的智能指针。并且引擎在处理回调方面抛弃了过去的函数指针的形式,而是采用更加安全方便的仿函数

引擎包含的模块有:

  1. 资源管理
  2. 渲染系统
  3. 节点系统
  4. UI系统
  5. 动画系统
  6. 事件系统
  7. 音频管理
  8. 任务调度系统
  9. 外设输入管理

引擎种各个模块并非完全独立的,有些模块之间存在依赖关系,有些模块仅仅是为了架构清晰而提出的,实际上部分实现已经渗透到引擎的各个模块。接下来简要的说明各个模块的功能。

核心系统是整个引擎各个模块的公共部分,提供了调试、一些便利的工具类和宏以及数学库。其中数据库可以充分利用现代CPU的SIMD特性,更快对各种矢量、矩阵进行运算。

渲染系统与节点系统、UI系统是密切相关的,他们也是引擎的核心所在。渲染系统对下封装了DriectX11的功能,如着色器、纹理、渲染状态等;对上为节点系统、UI系统提供了一套渲染机制,使其可以不必太关心具体的渲染细节,而专注于做引擎的逻辑。

事件系统和任务调度系统是可以起到连接引擎与游戏的桥梁,游戏可以通过监听各种事件来获取引擎的状态。同时这两个模块也为游戏开发提供了极大的方便,事件机制可以解决游戏中复杂的对象关系之间的耦合,定时器则方便游戏进行多种时间相关的处理。

动画系统为引擎种可执行动画的元素实现了简单的动画(位移、帧动画等)

资源管理 包括游戏资源(纹理、声音等)管理与系统资源管理(句柄、内存等)。对于游戏资源采用缓存机制,在游戏加载时载入缓存,如果再次使用相同的资源则不必重新加载。对于系统资源采用基于父子节点树的管理方式和基于智能指针1的管理方式。

二、引擎目录

引擎目录如下图所示(以1.0.3版本为例)
2D游戏开发 - SkyGameEngine2d 引擎架构 | 目录结构 | 引擎入口点_第2张图片

  1. bin 目录存放引擎编译后产生的文件,如debug\SkyGameEngine2d_d.lib
  2. build 目录存放引擎的VS工程文件,如SkyGameEngine2d.sln
  3. doc 目录存放引擎的文档,可浏览器打开index.html 本地阅读文档
  4. empty_template 目录为游戏项目的一个空模板,一般不需要关心该目录,仅供引擎工具新建一个项目时使用
  5. include 目录包含引擎的头文件
  6. sample_game 目录存放引擎的示例游戏项目
  7. src 目录存放引擎的源码
  8. test 目录存放引擎的测试项目
  9. tool 存放一些工具相关的数据或者项目

2.1 src目录介绍

src目录如下(以1.0.3版本为例)
2D游戏开发 - SkyGameEngine2d 引擎架构 | 目录结构 | 引擎入口点_第3张图片

  1. action 包含了动画系统的实现
  2. audio 音频管理的实现
  3. base 引擎的公共基础库实现,比如事件系统、数学库、颜色等
  4. example 某些api的用法。仅供文档 对其进行引用 ,已说明某个API的示例用法,文件不会参与到引擎编译
  5. external 第三方库
  6. node 节点系统的实现
  7. ui UI系统的实现
  8. utility 一些工具类\函数\宏定义
  9. win32 与windows平台相关的代码
  10. render 实现渲染系统

三、项目目录

参看教程 2D游戏开发 - SkyGameEngine2d 创建一个游戏项目 创建一个新项目。
项目目录如下图:
2D游戏开发 - SkyGameEngine2d 引擎架构 | 目录结构 | 引擎入口点_第4张图片

  1. build 文件夹为游戏工程文件存放的目录
  2. res 文件夹为 游戏中的资源文件 (图片、声音等)存放的目录
  3. sky_game_engine2d 文件夹为引擎相关的文件(工程文件、源码等)
  4. src 文件夹为游戏源码存放的目录

重点说明src目录如下所示
2D游戏开发 - SkyGameEngine2d 引擎架构 | 目录结构 | 引擎入口点_第5张图片

  1. framework 引擎框架入口
  2. scene 游戏场景的实现

引擎入口实现文件如下所示
2D游戏开发 - SkyGameEngine2d 引擎架构 | 目录结构 | 引擎入口点_第6张图片

四、引擎框架入口点分析

4.1 main.cpp 分析

首先分析main文件

//main.cpp 

int WINAPI WinMain(
	HINSTANCE hInstance,
	HINSTANCE hPrevInstance,
	LPSTR lpCmdLine,
	int nCmdShow
)
{
	UNREFERENCED_PARAMETER(hPrevInstance);
	UNREFERENCED_PARAMETER(lpCmdLine);

	std::unique_ptr app_delegate = std::make_unique();
	auto app=Application::getInstance();
	app->setAppDelegte(app_delegate.get());
	return app->run();
}

WinMain() 为win32应用程序的主函数【类似于 main() 】。在该函数中首先创建一个GameAppDelegate对象,然后获取程序实例并且设置代理对象。最后,程序实例对象app执行 run() 函数。run()函数为引擎工作的开始,它由初始化代码游戏循环退出清理代码 三部分组成。代码如下所示。

	// run 函数实现 
	int Application::run()
	{
		//1.初始化应用程序
		if (!initApp())
		{
			return -1;
		}

		//2.游戏循环
		this->loopApp();

		//3.退出游戏 清理
		this->clearApp();

		return 0;
	}

4.2 GameAppDelegate.cpp 分析

上一小节提到在主函数中首先创建GameAppDelegate对象,那么该对象在游戏中有何作用,这要从引擎基础架构的设计说起。

2D游戏开发 - SkyGameEngine2d 引擎架构 | 目录结构 | 引擎入口点_第7张图片

  1. IApplication提供了应用程序代理的设置以及Windows消息过滤器的设置。开发者可以通过消息过滤器来自定义的处理系统消息。
  2. IAppDelegate接口为开发者提供了定义引擎运行的各个阶段的能力。比如设置窗口的尺寸、调整游戏帧率、初始化场景等。开发者需要继承该接口,复写其接口 即可,引擎在适当的时候回调用这些接口。
  3. IApplicationView接口提供了与程序视图相关的数据,比如当前窗口的大小等。

总之,引擎通过上述3个接口来描述游戏程序,分别处理 程序的基础逻辑、开发者自定义程序逻辑、程序的视图三个部分。IApplicationIApplicationView 接口均由引擎本身实现,而IAppDelegate接口由游戏开发者实现,来控制程序运行各个阶段的逻辑。

引擎工具在创建项目时 默认提供了 GameAppDelegate 类来实现IAppDelegate 接口,该类的实现均为默认情况在的设置,开发者需要根据实际项目调整

下面以默认的实现来说明如何通过代理(GameAppDelegate)控制游戏程序。

bool GameAppDelegate::appInit()
{
	//设置帧率
	auto app = Application::getInstance();
	app->setPerFrameInterval(1 / 120.0f);
	
#ifdef _DEBUG
	GameWorld::getInstance()->openDebugConsole();
	GameWorld::getInstance()->isDisplayRenderInfo(true);
#endif // _DEBUG

	//TODO 做自己想做的事情吧 。

	//开始场景 
	auto g = GameWorld::getInstance();
	g->pushScene(TestScene::create());
	g->start();
	
	return true;
}

appInit()为程序的初始化阶段,在该阶段可以对程序的初始化值进行设置,比如帧率(默认为60),亦可以加载一些游戏资源等等2。重要的是一定要在最后启动一个游戏场景,这样游戏才可以正常运行
注意:请勿在该函数中执行太多的耗时操作,这样会导致程序假死。

IAppDelegate接口作用如下表所示

接口名字 作用
appInit 引擎初始化后会调用,用来控制程序的初始信息
getWindowsSize 引擎通过该接口获取程序的窗口尺寸
appEnterBackground 当程序被最小化时调用该接口
appEnterForeground 程序从最小化进入正常窗口时调用该接口

更多文章见:SkyGameEngine2d 游戏引擎相关文章目录汇总

本节完
最后更新时间:2019年7月19日 21:27:40


  1. 这里指的智能指针包括 C++中的智能指针和WinRT中管理com组件的Com智能指针ComPtr ↩︎

  2. 该阶段引擎的基础组件其实已经初始化完毕,所以在该函数中几乎可以使用引擎中的全部API ↩︎

你可能感兴趣的:(SkyGameEngine2d,windows游戏编程)