我想写一些关于“移动代码”的内容。其实不是代码本身,而是关于“移动代码”的概念,以及它如何改变你对游戏中控制角色的理解。这篇文章其实并不适合程序员们仔细研读并批评我的代码。抱歉。我不是最好的程序员,我还在学习,但我想分享我过去三四年游戏开发过程中的心路历程。
认为在 2D 游戏中让角色移动是一件简单的事情,其实有点错误。当我开始开发《ANOTHEREAL》时,那是我第一次尝试让角色移动。我之前的游戏《ESC》在背景上使用了文本框。我之前参与开发的其他游戏都有才华横溢的系统设计师,他们在我接触任务和敌人设计之前几年就完成了移动代码。
但应该很容易吧?这是一款 2D 游戏。角色的位置由 X/Y 坐标决定。只需根据推动的方向调整 X 或 Y 即可。很简单,对吧?
嗯,有点儿。你可以这么做。事实上,这就是 Astra 移动代码的第一个版本。她是一个非常简单的精灵,当你按下方向键时,它会均匀地调整 X/Y 坐标。
但你很快就会发现,哦对了,这玩起来感觉不太好。光是……拖动精灵到处走,其实挺无聊的。
然后你就开始琢磨它了。你在网上找了各种关于角色控制器的教程。哦哦,好吧,好吧,真烦人。你需要定义移动速度,然后用移动方向乘以移动速度来调整 X/Y 坐标。
我曾经尝试过一个有趣的想法,因为我痴迷于 2D 游戏中流畅的动量,那就是在按住方向键时调整速度。Astra 的第二个移动代码版本中,她的速度会根据移动时间的长短逐渐变快或变慢。虽然变化幅度不大,但确实感觉……挺酷的。如果你喜欢角色不受你操控的那种感觉,那就试试吧。
这也让她感觉自己像个幽灵。因为这就是她的全部。她喜欢像幽灵一样的感觉。所以我想帮她解决这个问题。
最终,这个想法很糟糕,因为我需要一定的精准度。这款游戏需要玩家与物体互动,并且要了解敌人相对于自身的位置。
(不过,当您还不太在意游戏控制时,此代码在介绍期间仍然存在于一个序列中。)
2D游戏中的碰撞也很奇怪。你可能会想,这就像,好吧,我只要设置你不能移动的区域,你就不会去那里,对吧?
嗯,有点儿。但实际上,你的玩家角色会寻找某种类型的物体。
让我们退一步来谈谈预知。
我在编程过程中很快学到的一件事是,编写游戏脚本通常需要运用超能力。当你打算做某件事时,游戏可以在你真正行动之前准确地知道你要做什么。事实上,这一点非常重要!
想象一下 RPG Maker 不断模仿的那种老式 RPG:游戏世界由网格状的图块构成,按下方向键即可移动到下一个图块。这里的移动很简单,就像菜单一样。按下方向键即可自动移动。但当你按下按钮后,它也能预知你想要移动到的图块是否可用。根据这种预知,它会改变你的角色的反应。是移动,还是发出“啊!”的一声并发出小声的提示。
对于更复杂的移动代码来说,通常也是如此,只不过你需要检查角色移动的每一帧。这样,系统就能预知你接下来可能的动作,看到那个像素,然后要么说“好的,继续前进”,要么说“等等,我们不能去那里”。然后发出“嗚”的一声,并发出一点声音。(Astra 实际上不会这样做。)
这一切当然很好,但是当你遇到不完全平坦的边缘时会发生什么呢?在这个充满物体和墙壁的宏大世界里,不仅仅是瓷砖,有时你会遇到倾斜的碰撞,或者,上帝保佑,遇到一个圆圈。
在这里我们可以向工具包中添加另一个有趣的比喻:激光扫描。
如果你熟悉 3D 游戏或第一人称射击游戏,你可能对光线投射有所了解。简单来说,引擎会在空间中的两点之间绘制一条假想线,并为你提供信息。其实,你也可以在确定移动方向时这样做。这有点像预知的工作原理,只不过现在它不再根据你的确切动量和方向来确定你的下一个位置,而是通过发射激光来确定其他信息:如果你不能直线移动,那么根据你摩擦的表面角度,下一个可以移动到的空间是什么?
所以现在你有了一个精神实体,它随时都完全清楚自己的下一步动作,并向前方的空间发射一道激光来告知他们做出决定。
这样做的结果是,当你按住左键时,你的角色将以合乎逻辑的方式沿着有角度或弯曲的表面行进,而不会以不合逻辑的方式卡住。
但我们还没讨论动画呢。目前,阿斯特拉还只是个四处滑动的石像。
在一个资源无限的理想世界里,我会给每个角色一个奢华的8轴旋转精灵图。这是我在玩《地球冒险3》时不断思考的问题。让每个角色都能绕着所有轴旋转感觉很棒。然而,作为一个想要发行游戏的女孩,我不得不做出一些艰难的决定:4个角色的旋转方向,每个旋转方向一个移动动画,以及每个旋转方向一个待机动画。即使是待机动画也相当奢华了,而且除了主角之外,我不打算为其他角色制作复杂的动画,但就是这样。
话说回来。如何确定角色面向的方向?用什么精灵图?一个更简单的方法是每次按下方向键时改变方向。但是,如果同时按下两个方向键会发生什么?哪个方向优先?嗯,你可以使用动量。这是我最先尝试的。因为阿斯特拉会跟踪她的 x 轴速度和 y 轴速度,所以你可以看到哪个速度更快,以及她在这个轴上的移动方向。但是,如果你沿对角线移动呢?在什么时候从上到左?从下到右?
这时,我们会迷失在有趣的逻辑谜题中,一旦看起来和感觉控制起来很好,这些谜题最终就会得到解决。
但接下来你得想想:如果你用的是带模拟摇杆的控制器,会怎么样?你会把它当成像十字键或方向键那样的开关吗?
就我而言,摇杆上缺少模拟输入让我感觉很不舒服。我安装了一个全新的控制映射框架(Juju Adams 和朋友们为 GameMaker 开发的输入库),才让模拟输入正常工作。但接下来的问题变成了如何调整我现有的运动代码以支持模拟输入?
再次,移动速度才是关键所在。由于模拟输入在两个轴上测量的是介于 0 到 1 之间的分数,因此它必须转换成输入的分数,而不是简单地说“是的,我按下了按钮”。不过,有趣的是,根据我之前编写的移动脚本,它有 4 个方向和 1 个速度。
就我而言,答案是回到我们的老朋友“朝向”。因为我通常可以确定阿斯特拉在任何时间点的朝向值是最大的,所以我可以根据该方向的模拟输入检查她的朝向,并调整移动速度。(这里需要设置几个最小/最大限度,因为模拟输入的保真度可能会让你做出一些非常愚蠢的亚像素速度)。
巧合的是,我也可以使用相同的值来调节动画速度,以便 Astra 调整她的步伐以匹配相对移动速度。
好了……就是这样。这就是我尝试制作一款手感极佳的 2D RPG 的完整历程。
但我甚至没有提到任何有关战斗运动的事情,因为那是完全单独处理的。
好了,今天就到这里。现在,你们可以尽情享受这个知识:我脑海中我们亲爱的主角阿斯特拉的形象就像一台精神状态机,不断用激光扫描她周围的环境,并运行逻辑谜题来决定何时改变她的朝向和速度。
原文: https://blog.radicaldream.land/dev-log-miscellany-moveing-in-anothereal/