LOADING...

加载过慢请开启缓存(浏览器默认开启)

loading

做个 3D 游戏来纪念宝可梦 25 年小智的夺冠退场

2022 年,11 月 11 日,在这天,来自真新镇的小智终于成了宝可梦世界冠军!

那些年,在不同地区的遗憾:

  • 1999年石英联盟16强
  • 2002年城都联盟8强
  • 2005年丰源联盟8强
  • 2010年神奥联盟4强
  • 2013年合众联盟8强
  • 2016年卡洛斯联盟亚军

到现在,终有回响:

  • 2019年阿罗拉联盟冠军
  • 2022年世界锦标赛冠军

25 年的旅程,也终于迎来了终点,小智退场。

自己谈不上最喜欢的动漫是宝可梦,但宝可梦毕竟是从儿时就有的记忆,且一直延续至今,感情很是微妙的,所以打算写个东西来纪念下。或许游戏是最贴和的,可是我并未有任何游戏编程经验,一下就有点犯晕了……

思来想去,就做一个中国象棋吧,加点 AI,自己也就可以在 Linux 下玩玩了,反正 Linux 下没啥可玩的中国象棋。

说干就干,那就开始规划,首先是游戏所需:

  • 玩法
    • 规则
    • 控制
    • 人机
  • 界面
    • 图形库
    • 模型
    • 游戏引擎

但实际上对于大部分棋类,都是在 Board 和 Piece 这些基础物件间控制操作的,那么可以这样来划分包:

  • stuff 基础包,提供控制和基础物件
  • game 游戏包
    • dark 暗棋规则
    • classic 中象规则
  • bot 提供规则

于是乎,就可以通过组合 来成为不同的游戏。

我一直认为在画界面,写终端界面是相对容易的,所以觉得先出个 tui 界面的来测试游戏正确性,是比较有可行性的,于是有一个界面的包:

  • appearance
    • text 提供 tui 界面操作
    • pokemon 提供宝可梦界面操作

结果发现 Java 的包 tui 库,可谓是惨不忍睹,由于我不是使用 Openjdk,而是 Graalvm,所以也试了 Nodejs 和 Python 的相关库,结果问题多多:

  • Node.js 在 Graalvm 下是独立的应用,跟 Graaljs 并不一样,也并不支持 AOT,而 JavaScript 下的 tui,像 blessed 和 ink,全是需要 Node.js 的运行环境的,在 Graalvm 下,有一些兼容性问题,如颜色不能正确显示,而且在 Graalvm 的 --jvm 下卡顿严重,占用资源也高。
  • Graalpython 支持 AOT,但是几个 tui 库都有问题,blessings 和 textual 都是缺少 Python 动态库,Graalpython 对于像 cursor 这种正常 Python 都会带的动态库都没有实现。pytermgui 虽然不需要额外动态库,但是却在 Graalvm 下有各种很基础的错误。

靠链接其他语言还是行不通,或者说比较折腾,后面发现 Java 下面有个叫 lanterm 的库,我其实不需要它提供的界面框架,只需要它的事件,在此过程有两个问题:

搞完 tui 验证程序可行性后,就可以开始进行 3D 界面的编程了。一开始我想的方案是以前被吹得很厉害的 JavaFX,后面才发现真搞 3D 用它是根本不切实际的:

  • 现在大多数 JDK 已经没有带上 JavaFX,要自己去折腾,如找 Gluon 家的。
  • OpenJFX 对 3D 模型的支持也不够好,只有一个叫 interactivemesh 的闭源库,支持少,比较老,交互缺,只能作为 viewer 去操作动画。

所以最后找了 Java 下的游戏引擎 JmonkeyEngine,虽然使用者少,帮助不够多,但是起码是能正常工作的,在 Gradle 下加入依赖,就可以在 vim/emacs 或者 vscode 上面进行开发测试了。在游戏引擎的帮助下,3D 编程就显得特别容易,只剩下建模这块比较麻烦,在折腾了两天 blender,才对不同格式,和贴图什么的比较了解。

在快 10 年的低压商务本上开发完,最终只能开低渲染:

ff07f23127691b153a0f4cf20104469d