我最近创建了一个新网站,并完成了一个名为Pascal Penguin的冒险游戏。 这个游戏最独特的事情之一是它是用Rust编写的,并且由于WebAssembly而可以在Web浏览器中运行。 WebAssembly仅在大约一年的时间内才成为主流,因此创建这样的游戏的并不多。 我想分享一些有关Rust的经历:我是如何开始的以及如何到达这一点。
长期以来,游戏开发一直是我的爱好。 在2015年中期Rust发行之前,我一直在用LibGDX用Java进行gamedev。 由于这是一种爱好,所以我选择了喜欢的技术,但这并不是说没有挫折感。 除了冗长之外,我对Java的最大挫败是,我发现自己不得不在编写惯用的Java代码和编写具有不错性能的Java代码之间进行选择。 例如,LibGDX API鼓励使用其对象池实用程序和将公共本机数组作为字段的可调整大小的专用数组实现。 这些不是Java惯用的做法,但是对于使游戏平稳运行很有用。 当您需要精于创建对象时,我想是时候找到一种新语言了。

我是通过阅读他们的在线书来学习Rust的,当时这本书看起来很不一样。 那时还短一些,更像是一本教程,而不是一本完整的书。 我发现许多东西很吸引人:零成本抽象,具有单态化的特征和泛型,所有权范例,与模式匹配相结合的灵活枚举,符合人体工程学的错误处理,内存有效的集合等。但是从根本上讲,Rust是一种安全的语言,这意味着使用Rust进行开发并不容易出错,同时仍然是一种高度可预测的高性能语言。 我观察到,当我编写Rust代码并达到编译代码而没有错误消息的程度时,它可能可以正常工作并且效率很高。 我认为这就是使该语言对许多人而言具有吸引力和力量的原因。
Rust周围也有一些出色的工具。 Rust编译器本身会给出有用的警告和错误消息。 Cargo依赖性管理工具非常简单,可以创建可复制的版本。 任何人都可以轻松上传crates.io中央存储库。 生成的html API文档是我在任何语言中看到的最有用的文档,所有公共包装箱的文档都是在docs.rs上构建和托管的。
因此,我在Rust中进行了游戏开发试验,但最初并未尝试通过网络浏览器运行游戏。 当时,有一个很棒的教程ArcadeRS,展示了如何使用SDL2制作Rust游戏。 不幸的是,该教程不再是最新的,该站点已被删除。 在进行项目时,我认为提取一个可重复使用的“层”(针对我的需求)是一种很好的做法,该层可将游戏逻辑与游戏所需的资源管理,渲染,音频和其他接口分离开。 我还决定使这一层开源,并成为Gate库。 为了解决这个问题,我创建了一个简短的开源2D平台程序,此后称为Chirperjax。

大约在这个时候,我听说了一种称为WebAssembly的新技术。 因此,Rust可以被编译为在浏览器中运行并获得接近本机的性能。 我知道我必须尝试一下,尽管它比我通常喜欢使用的最前沿。 将游戏作为爱好开发的问题之一是,人们倾向于警惕在计算机上下载并运行可执行文件,这是理所当然的。 通过浏览器托管在沙盒环境中运行的游戏,可以让更多的人玩游戏。 我的第一个尝试是使用emscripten的SDL2支持来编译Chirperjax,但是我无法使其正常工作。 因此,我完成了一些针对Rust的wasm32-unknown-unknown目标的教程,并学习了如何从Rust调用JavaScript方法以及如何从JavaScript调用Rust方法。 由于现代html能够自行创建交互式的视听体验,因此除了howler.js之外,我不需要依赖SDL2或其他附加库。 这使整个应用程序轻巧,并给了我很多控制权。
请记住,我在Rust的WebAssembly工具还不成熟的时候这样做。 但是我确实设法将Gate构建到WebAssembly,并于2018年1月在线发布了Chirperjax。这样做并看到人们喜欢玩它之后,我决定使用相同的工具创建一个更具野心的游戏。 那是Pascal Penguin冒险之旅的开始,该冒险之旅于2018年12月完成。对我而言,这基本上是一个为期一年的项目。

简而言之,这就是我的经验。 当然,我可能还有其他途径,例如学习MonoGame或Unity。 但是,当我第一次偶然发现Rust时,我感到它正是我想要的一种编程语言,并且因为我只是出于娱乐目的而做,所以我决定通过更主流的gamedev选项来学习它。 我学习Rust并没有太多困难。 当然,我曾经有段时间引用“与借阅检查器抗争”,但是我了解到我可以重新安排对象模型,并想出更自然地与借阅检查器一起工作的思想,这也提高了我的代码质量。 如果我有一些抱怨,那就是缺少快速教程和不成熟的库。 但是总的来说,我在Rust方面的工作效率很高,我鼓励其他人尝试一下。