使用 React+Redux 编写 RPG 游戏(翻译)

2019-03-10

前言

本文的作者是 Andrew Steinheiser,文章源链接为 Making an RPG with React + Redux,我将其翻译成中文。

几个月前,我开始用 ReactRedux 开发一个开源的角色扮演游戏,名称为 React RPG

现在我已经发布了第一个版本,我向在本文中聊聊我的动机、目标、打算,和学到的东西,以及使用 React 开发游戏的好处与坏处。

动机

从我记事起,我就一直想做一款游戏。最近我也一直在努力为更多的开源项目做贡献。

有了这些想法,我觉得我的下一个 SideProject 项目需要是我自己的开源游戏。

大约在同一时间,我制作了一款 Pi Linux 平板电脑,其中一款有趣的游戏(能在 3 Pi A+ 上真正跑起来)是 The Battle for Wesnoth

我真的很喜欢开源社区能够帮助将游戏的故事线扩展到一些令人敬畏和独特的内容。另外,如果你喜欢回合制策略,游戏也非常有趣。

所以在我的脑海中有了这个游戏的想法,我决定看看如何利用我已经使用过的东西(React)去创造它。

这也会给我一个很好的机会去学习更多关于 Redux 的知识。

在找了几个替代的 JS 游戏框架(phaser, pixi, ……)后我放弃了他们。我想要么使用 React,要么使用Unity。

但就在那时,我发现了 Danger Crew 的这个演讲,这是一款 Pokémon 风格的策略游戏,使用 React 和 Redux 编写。

在整个演讲过程中,开发者详从整体上上细地介绍了他们是实现游戏特性的,并且鼓励他人使用 React/Redux 来开发游戏。

最终,这个演讲推动我进行尝试。

目标和打算

在决定使用 React 后,我想让游戏机制易于编写。所以我决定做一个回合制的地牢爬楼游戏。

玩家获得瓦片(Tile)地图鸟瞰视角,当然图像是像素风格。

我的灵感绝对来自于传统的 Rogue-like 类游戏,比如《像素地下城》。我喜欢它们以寿命短、运气好的玩法而闻名。

我想让项目环境对其他开发人员来说更容易,因此我决定使用 create-react-app

通过使用 CRA,它帮我们处理了 webpack,我们就不用管它了。

因为我们使用 React,因此我们使用网页发布我们的游戏,但是发布移动端也很容易。

我创建了一个 React Native 应用,他不过是一个带有游戏 URL 的 WebView。

现在,当我将更新提交到网站,移动 APP 不有发布新版也同样更新了。非常棒!

我还想鼓励人们做出共享,通过允许他们立刻看到 staging.react-rpg.com 中 beta 的测试特性改变。

为了实现这个,我用 AWS 创建了一个 CodePipeline,来自动构建并发布 Master 和 Staging GitHub 分支。

一旦修改被合入,五分钟内就能在 URL 中看到更新。

学习

构建游戏机制是到目前为止这个项目中最耗时和最难的部分了。

但是,它带来了很多学习的机会。

制作战争迷雾机制给游戏玩法带来了巨大的进步,但我一开始不知道怎么来实现它。

最后,我在每个 Tile 上设置了一个 explored 值,来跟踪当前的瞄准框。

现在,当地图呈现每个 tile 时,它会检查它是否应该未被探索,是否应该被探索(但不在视野中),或者是否应该在玩家的视野中。

让游戏拥有 Pokémon 类型的视口(viewport),而不是仅仅展示整个地图(见下图),是摆在我面前最艰巨的任务,但是如果我想将游戏发布在手机上,我就不得不实现它。

辛运的是,这比我想象中要容易得多!

我重新看了 Danger Crew 的演讲,并且注意到他对视口的解释。在那之后,我知道我需要做什么。

首先,我必须让玩家始终处于中心位置。为此,我只是在玩家移动时将地图相对于屏幕左上角移动。

之后我在玩家周围画了一个框,大小为视口的大小。我给这个框 overflow: hidden 属性,使其始终跟随玩家。

在构建项目的过程中,我还学到很多关于 Redux 和 HTML/CSS 的知识。

在最初将游戏发布到 Twitter 和 Reddit 上后,我得到了许多良好的反馈。

通过反馈,我使 HTML 更加语义化,使 CSS 遵守 BEM命名约定,我还重构了 Redux stores(感谢 Mark Erickson 指出 clonedeep)。

在这个大的重构之后,很多奇怪的副作用都消除了,一切都变得更容易预测,更容易操作。

优点

  • 热更新带来的快速开发(感谢 React
  • Redux DevTools 带来的时间线重放调试
  • 易于发布到 Web、移动端、原生桌面端(感谢 React NativeElectron
  • 保存和加载游戏状态非常容易(感谢 Redux
  • 不需要发版就能快速更新移动 APP(感谢 RN WebView

缺点

  • 处理浏览器兼容性(🖕Safari)
  • 构建新的游戏功能比使用实际的游戏框架花费的时间要长得多(pixi, phaser, unity

总结

React 对于构建大多数游戏来说不是最好的工具,但是,对于某些类型的游戏,它可以很好地工作,并带来一些好处。

我喜欢做这个项目,并且在做的过程中不断学习,所以这对我来说是值得的。感谢你的阅读!

如果你想做贡献的话,请参见 GitHub repo