最爱午后红茶

游戏技术

日期图标
2024-07-19

技术选型

目前我直接使用 DirectX11 进行开发,为什么不使用游戏引擎(比如 UE、Unity、Godot、Cocos2d、SFML 等等)?

  • 一个原因是想拿 DirectX11 练练手。而且这是个 2D 游戏,相信直接用 DirectX11 开发也不会有太大的难度。
  • 另外我也想了解一些引擎背后的东西,当然使用开源的游戏引擎也能做到,但是有一些学习成本。不是说自己不愿意付出这些精力,只是担心要学到能动手的程度那时开发 DNF 的热情已经消退了。而使用 DirectX11 的话我已经有思路了。
  • 有些游戏引擎实在是过于庞大了,我目前只是做着玩,可能后面如果重构的话会考虑游戏引擎。

有考虑过使用物理引擎,比如 Box2d,但后来想想我只需要物体按照一定的速度朝着指定的方向去移动,以及碰撞检测的功能,所以还是自己写方便一些,可以做一些为该游戏定制化的东西,不过我有参考 Box2d 的一些接口的设计。但自己做方便也只是现在方便,后面如果出现一些复杂的物理运动,估计还是逃不掉。

需要具备哪些知识呢?

  • C++ 以及 Windows 编程基础(窗口、消息之类的
  • 图形学基础
    • 理论基础可以看 Games101,需要看完 Sharding 及其之前的内容,事实上我也只整理到这,目前够用。
    • 实践基础可以看图形学的龙书 Introduction to 3D Game Programming with DirectX 11 前 9 章的内容,目前我只整理到第 8 章(没有时间有点更不动了),但是第 9 章 Blend 对于做出一些特定的透明效果非常重要。本程序着色渲染相关也是使用了书中示例所用的已经被微软从 DirectX SDK 移除掉的 Effect 框架。
  • 游戏架构知识
    • 《游戏编程模式》:目前游戏架构设计很大一部分依照该书去做。
    • 《DirectX11 游戏编程入门》:好像是比较偏门的书籍,我也不知道怎么找到它的,比较有印象的是它会告诉你如何使用 DirectX11 绘制精灵,还有鼠标键盘的处理讲的也蛮详细。

用到了哪些第三方开源的东西?

  • ThreadPool:管理多线程。目前没怎么开线程,先简单用着。
  • PicoJSON:json 解析,只有一个头文件。目前主要用来封装自己定义的事件,还有一些配置文件。
  • TinyXML-2:xml 解析,DNF 的音效是在 XML 文件通过别名去映射到具体音频的。
  • libzplay:播放音频。事实上目前是用它来解码音频然后搭配 XAudio2 播放
  • spdlog:日志管理,搭配 baretail 实时监控日志。

其他

我是万万没想到在 DirectX11 上渲染文字会是一件麻烦的事情。网上有各种各样的方法,我目前的选择是 DirectWriteCustomTextRenderer 那套。

不过测试下来发现这个方案对性能好像有不小影响,实测严重影响帧率(也可能是自己没用对)。后面可以考虑下 FreeType

后面证明确实是自己方案不对,冤枉 DirectWrite 了~,搭配适当的缓存策略就能够比较高效地渲染文本。FreeType 没有去尝试,不过有测试过小一点的 stb_truetype,就一个头文件(整套 STB 工具库里面还有蛮多不错的实用工具,基本都是 include 下头文件就能用),集成进去也还算方便,不过渲染中文会有些麻烦,先作为备用方案。


游戏资源

说说游戏资源(包括贴图、数据、音乐、音效等),DNF 的目录里面有两类文件非常重要:

  1. .NPK 文件(有多个)
  2. .pvf 文件(其实只有一个文件)

NPK

其中 .NPK 文件是一种由 DNF 开发团队自定义格式的文件,几乎所有游戏里面用到的贴图和音效都存放在这类文件里面。具体来说就是 NPK 里面定义了特定的字段表示某贴图(或音效)的名称,又有别的字段表示该贴图(或音效)的实际数据内容在整个文件里面的偏移大小,每一个 NPK 文件都存储了多个贴图(或音效)。我是直接写程序解包 NPK 提取里面的贴图然后按需加载在内存里面的。当然,也可以使用第三方工具(网上有不少人针对 NPK 解包做了一些好用的工具)把 NPK 解包成 png(或其他图片格式)存储在硬盘里面备用,但我觉得那样会存在大量的目录和小文件,所以就自己动手写提取 NPK 的代码。

pvf

.pvf 文件也是由 DNF 开发团队自定义格式的文件,只有一个(Script.pvf),但是极其重要。如果你不懂 pvf,想要动手去复刻 DNF,那将无比艰难,因为 pvf 会告诉你:

  • 每个角色的属性是什么、技能都有哪些、技能的数值伤害、角色技能对应的皮肤以及装备的贴图序列帧的路径
  • 每一个地图是由哪些贴图组成的,以及地图里面的 NPC 的贴图还有他们的坐标,地图对应的音乐,还有地图与地图之间的连接
  • 攻击和受击碰撞框的大小和坐标
  • 贴图应该采用哪种 blend 效果
  • 地图的可移动区域有哪些
  • ...

毫不夸张地说,几乎所有游戏数值都存储在 pvf 文件里面。它跟 NPK 一样,也是由大量的小文件组成的。

NPK 迭代了好几个版本,最初的版本没有加密,清楚它的封包格式就能解了,后面的版本有简单的加密;而 pvf 是有加密保护的。那我是怎样能读取这些文件的?这得感谢互联网,只要你愿意去找,总还是能找到办法的。具体的细节就不拿出来说了,这些应该不好在明面上说(研究人家的资源也就算了,公开出来的话就有点那个了~)。


游戏代码不开源。

* 未经同意不得转载。