• Celeste 机制研究


    0. 简介、惯例、总论

    Celeste (塞莱斯特) 是一个具有优秀手感的平台跳跃游戏. 虽然操作所使用的按键很少, 但是却有着复杂的组合机制. 在游戏实现上, Celeste 是一个锁定 60 帧 (实际帧率 60000/1001 帧)、对于输入序列确定性的游戏 (尽管某些机制具有 RNG , 但是这些 RNG 使用的种子是相对于地图名称固定的), 同时 Celeste 具有方便的 TAS 工具, 这使得其机制研究变得相当容易. 在以下行文中, 我们假设其帧率就是 60 帧整, 以不加单位的 pps (每秒像素数) 值来表示速度, 以不带单位的 pps/f (pps每帧) 值表示加速度, 以 x,y 表示横纵向速度, 以 Dv 表示单次加速度, 以不加单位的 dspf (每帧体力值变化) 值来表示体力值变化. Celeste 的碰撞判定和伤害判定都是以绘制的像素为基础的, 内部的位置表示是精确到亚像素的, 在绘制的时候会对位置的小数部分舍入.

    1. 基本操作


    • 在平地上按住方向键 Madeline 可以跑. 跑以 50/3 的加速度向两个方向加速, 能达到的最大值是 90, 因此在 6 帧内达到最大值. 如果不输入方向, 则会以 50/3 的减速度停下来. 如果速度在 90 以上, 则按住同向方向键会以 20/3 的速度减速, 按住异向方向键会以 50/3 的速度减速, 按下键会以 25/3 的速度减速, 如果同时按下左右和下键也是以 25/3 减速.

    • 滞空
      Madeline 在滞空时, 按住左右方向键会以 65/6 的速度加速, 不按方向键会以 65/6 的速度减速至 0, 最大可达 90 的横向速度. 横向速度超过 90 时, 按住同向方向键会以 13/3 的速度减速至 90. Madeline 最大的下落速度是 160. 为了方便起见, 我们将下落速度记为正, 上升速度记位负. 当 Madeline 的速度在 [-40,40] 的区间内时, 如果 Madeline是冲刺结束的状态或者按住跳键可以以 7.5 的加速度下落, 否则以 15 的加速度下落. 如果 Madeline 的下落速度大于 160, 不按住下键会以 -15 的加速度下落直到速度达到 160, 按住下键会以 5 的加速度下落直到速度达到 240. 在游戏中基本不可能获得超过 240 的下落速度.


    • 在游戏中有多种跳跃形式.

      • 冲刺取消跳跃.
      • 踢墙跳.
      • 抓跳.
      • 平地跳跃.

      冲刺取消跳跃和抓跳都有复杂的交互机制, 会在之后阐述.
      平地跳跃最简单: 会获得 D+40,-105 的速度. 如果是落地起跳, 则落地会先获得一次落地减速然后计算后面的速度. 如果地面拥有横向或纵向移动速度, 则这个移动速度会被叠加上.
      踢墙跳对于非移动块的机制也相对简单: 会以 130,-105 的速度跳出. 如果是以不按方向键的跳跳出则可立即普通的滞空状态减速, 否则会以 13/3 的速度减速至 90 后按滞空计算. 因此, 不按方向键的踢墙跳可以更快的减速,这使得不消耗体力爬墙成为可能. 对于移动块的机制 非 常 玄 学, 但是关于方向键的部分还是一致的. 不负责任的推测: 移动块的速度是内部以速度-曲线描述的, 而其值是连续的(这里我们将浮点数或者定点数视为连续值); 但是机关块的计算位置被取整到了像素值, 因此表观上机关块的速度一定是 60 的整倍数. 这使得在 TAS 的时候计算机关加速变得极其困难. 按这个理论, 我推测应该是获得 D90,-105. 其中 D90 是一个估计值. 另外 Celeste 计算的亚像素特性导致了更多奇怪的现象, 总体而言只能多尝试.
      一直按住跳跃键, 纵向速度会保留 12 帧.


    • Madeline 拥有 110 体力值, 在休息 (落地或捡水晶) 后会完全恢复. 在抓墙不动时, 会以 1/6 速度减少体力值. 在向下爬时不消耗体力值. 在向上爬时以约 0.8 速度消耗体力值, 每次抓强跳消耗 27.5 体力值. 向上爬会以 -45 的最大速度爬行, 以 -15 的加速度加速, 在速度超过 -45 时以 15 减速. 向下爬会以 15 速度加速, 最大速度 80. Madeline 在安全的平台旁边爬到足够高并继续按向上爬会自动爬上平台, 但是这个操作在 TAS 或人类速通中几乎没有作用. 如果是不安全的平台, 那么 Madeline 不会完全爬到墙顶上. 抓墙时不按方向键或者按住向墙方向跳可以以 -105 的速度爬墙. 作为容错机制, 在墙边 2 像素的位置也可以抓墙, 如果在运动情况下则会扩展到 4 像素. 如果按中性(即不按左右方向)抓墙跳则可以隔空抓墙.

      按中性抓墙跳可以爬火墙、冰墙: 这两者的伤害箱刚好在体积箱4px外,因此以像素精度可以踢、用中性抓墙跳可以抓爬、甚至在移动而横向速度和亚像素位置足够好的时候也可以抓墙爬. 同样, 火墙和冰墙刚好可以做抓角加速 (这会在后面被阐述), 同样也要求像素精度甚至亚像素精度.

      在上图位置松开跳键可以7帧后干净利落地停在平台的高度. 这要求亚像素位置在这个地方偏低处.

      同样,在上图位置也可以, 但这要求亚像素位置偏高.
      7 帧是停下来的最小时间, 因为你需要将 -105 的纵向速度减速到 0.
      朝向墙面的抓墙跳会给予 D-40,-105 的速度, 这可以用来保持高速或者快速回到墙面(在爬墙时用到).

    • 冲刺
      冲刺会暂停 4 帧 (在这 4 帧中 IGT 会走 1 帧; 磁带块不受这个时间影响, 因为磁带块必须与背景音乐同步. 这也是为什么速通选手会在磁带面等待时疯狂向下冲刺, 因为冲一次省 3 帧. 虽然很微小, 但是是白给的时间节省, 不要白不要). 在冲刺的第一帧中如果输入了方向键下, 则会使 (除了斜下冲以外的冲刺) 变成蹲姿. 如果斜下冲冲刺到地面则会变成蹲姿、然后横向速度变成 1.2 倍. 冲刺状态会在之后保持 10 帧, 每帧速度都不变且不会受到风的影响 (但是会受到移动块影响). 在这里可以引入 Speed 和 Velocity 值: Speed 就是物体所持有的速度属性, 而 Velocity 是物体更新位置所使用的速度属性. 在之前谈论的都是 Speed.
      冲刺的速度计算: 以时针 12 点方向为 0 度, 顺时针定角度 angle, 那么速度是

      fvec2 DashSpeed(fvec2 originalSpeed, float angle){
        fvec2 t=240*fvec(cos(angle/360*2*pi),-sin(angle/360*2*pi));
        if(originalSpeed.x * t.x > 0 && fabs(originalSpeed.x) > fabs(t.x))
          t.x = originalSpeed.x;
        return t;
      }
      

      这个算法的正确性可以由异变模式打开 360 度冲刺来验证.
      冲刺结束时, 速度重置会首先计算出此时速度的方向,然后做如下计算:

      • 当冲刺具有向下的速度时, 冲刺结束不重置速度; 如果向下的速度超过 180, 则会先以 -15 的速度降到 180.
      • 其它情况, 冲刺结束将纵向速度变成原先 1/2, 横向速度重置为 160*cos(angle/360*2*pi).

      注意在这个算法中, 斜下冲触地变成蹲姿后会被认为是横冲.
      这个算法的正确性同样由 360 度冲刺来验证.
      斜下冲冲刺结束后触地仍然会产生蹲姿并具有 1.2 倍横向速度, 由于此时已经不是冲刺状态, 不会受到速度重置的影响, 因此这是一个重要的叠加速度的手段. (很可惜, Celeste 中几乎没有叠加纵向速度的手段).
      冲刺开始时, 如果你离开地面 2 像素以内, 你会被拉到地面上; 如果在横冲中冲到里地面 2 像素以内的地方, 你也会被拉到地面上.
      在冲刺的第 11 帧后, 如果触碰地面则恢复充能; 在冲刺的 15 帧后才可以开始下一个冲刺.

    2. 伤害机制

    • Madeline 碰撞箱
      Madeline 和羽毛形态的 Madeline 有两个碰撞箱: 一个是用来检测物体碰撞的碰撞箱, 我们就称为碰撞箱; 另一个稍小的是用来做伤害判定的, 我们姑且称为伤害箱. 在途中, 我们以绿色标明 Madeline 的伤害箱, 用红色标明 Madeline 的碰撞箱. 在蹲姿, Madeline 碰撞箱的高度会减小, 这允许我们钻过一些缝隙.
    • 刺球

      刺球的碰撞箱如图所示, 触碰即死.
      某些被刺球覆盖的平台其实留有足够蹲姿冲刺进去的余量, 可以做 demohyper 恢复充能.

    • 刺是有方向的, 当你的速度有分量和刺同向时, 刺不会杀死你.
    • 时机
      检测伤害时总是用的刺上一帧的伤害箱, 因此同向运动的刺有时不会杀害你.

    • 如果有和刺对向的风,有时刺不会伤害你. 具体原理可能是伤害判定使用了 Speed 作为伤害箱移动依据?
    • 摄像机区域
      只有在摄像机区域内的物品会被计算伤害箱, 而摄像机的移动是有速度限制的; 因此只要飞得足够远出了摄像机区域便不受刺的伤害.

    3. 安全机制

    • 威利狼跳
      你在离开平台的几帧内仍然可以起跳. 离开地面的一帧也被认为是地面, 可以恢复充能.
    • 速度保留
      当你的速度能在 4 帧内绕过一个角, 那么你的(横向)速度将会恢复(不过会算上这之间的其它干扰).
    • 绕角
      注意虽然都是绕角, 但这和速度保留机制有区别. 绕角发生在身体的(一定比例以上)部分不受角阻碍时, 这时会重置位置到角的另一边.
    • 墙跳
      如果输入了 12 帧以内的中性抓墙跳, 然后离开墙面, 如果此时键入了方向,会被判定为墙跳并且得到与墙面反向的速度. 这个速度和原速度无关,因此可以用来快速减速. 同时, 这是一种保留蹲姿离开墙的办法.
    • 更大的交互判定
      如之前所述, 墙的交互判定有多几个像素. 事实上, Celeste 甚至允许你在墙面以下两像素抓墙, 用这个技巧可以在墙面以下抓墙跳, 可以带来一些路线改变.
    • 机关加速保留时间
      自离开机关或机关停止, 机关加速会保留 10 帧时间, 在这段时间里做被机关加速影响的操作都会获得额外的加速.

    4. 判定的间隙

    Celeste 是以帧为单位做判定的, 这导致了 Celeste 是离散的, 有些在连续时不可能的操作变为可能, 也有些在连续时可能的操作变为不可能. 但是总体而言, 因为帧率足够高, 常常可以微调亚像素位置来获得操作的可能性, 因此总体是有利的.

    5. 蹲姿

    进入蹲姿的方法有:

    • demodash: 在冲刺的暂停时间内, 输入下键, 而在暂停时间后以非向下的速度冲刺, 可以蹲姿冲刺.
    • 冲刺进入无法站姿进入的狭缝.
    • 蹲姿起跳.
    • 斜下冲触地.

    退出蹲姿的方法有:

    • 以 30 (?) 以上的速度下落.
    • 蹬墙跳.
    • 在蹲姿的时候试图冲刺.
    • 用普通跳跃打断冲刺.

    6. 冲刺取消

    • 普通跳取消
      在横冲的冲刺状态起跳, 如果是蹲姿则进入压身大跳, 拥有 325,-52.5 的速度; 如果不是蹲姿则进入普通大跳, 拥有 260,-105 的速度. 这个速度受机关加速影响, 压身大跳的纵轴初速度一定是同样情况下不压身的 1/2. 纵向速度会被保留 12 帧.
      在竖冲的冲刺状态或冲刺后 5 帧内踢墙跳, 可以获得 170,-160 的速度. 同样, 这个速度受机关加速影响. 一直按住跳跃键, 纵向速度会保留 15 帧.
    • 直愣愣撞墙取消
      可以用来停车.
    • 抓物品取消
      Theo 和水母.
    • 跳过剧情动画取消
      会重置除了速度以外的状态.
    • 绕角取消
      • corner jump/corner boost
        区别是亚像素级别的. 如果在获得一次抓墙跳之前就撞上墙则不能使横向速度 +40. 只要在 4 帧内绕过角就可以恢复速度.
      • corner slide
        似乎基本只用在无抓中. 斜上冲刺撞墙可以自己绕过角; 如果在四帧内绕过且绕过后冲刺时间已过, 则会转变成一个corner slide, 保留横向速度. (这里的描述不是很确定, 但是这个技巧确实存在而且我可以 TAS 出来)
      • 咖啡跳
        咖啡跳就是绕过墙角踢墙跳, 这也可以用来取消冲刺.

    7. 过面

    Celeste 存在两种过面: 横向以及纵向. 这两种过面都可以恢复充能; 横向除了恢复充能外不做其它事情(有些时候会有位移), 向上过面会强制一个长度为 10 帧的跳跃且这段时间内不能冲刺. 但是如果旁边有墙, 这个跳跃可以被打断, 比如名为 bubs drop 的技巧. 同时, 向上过面不会让前一面遗留的向上冲刺的打断过程消失, 因此可以切屏向上冲刺打断跳.

    8. 泡泡

    泡泡有个不短的 (而且算入 IGT 的) 停止时间给人反应, 但是如果在这段时间内键入相应方向的冲刺则可以提前启动泡泡. 这个冲刺键入不受之前冲刺时间的影响.

    9. 重生时间

    平台的重生时间比它上面的刺快一帧.

    10. 跳过剧情

    跳过剧情会重置横坐标, 这可以用来节省一些路程. (典型如 2A 和 5A)

    11. 果冻(梦境方块)

    • 穿墙
      当 Madeline 还有一部分在果冻内时, 她不会被墙夹死. 这可以用来穿墙.

    • 只要 Madeline 的碰撞箱穿过果冻就可以恢复充能. 这典型的使用于 2C TAS 中.
    • 出果冻
      • 反抓
      • 可以跳跃, 获得 D40, -105
      • 可以在果冻后的冻结时间再跳一次, 继续获得 D40, -105
      • 果冻的冻结时间可以键入一个下冲跳, 获得 325, -52.5

    12. 弹簧

    是大便. 会强制重置速度.

    13. 弹球和喷喷鱼

    在触发喷的那一帧键入与喷相同的方向可以获得更大的速度.

    14. 熔岩

    很难用, 我裂开.

    15. 浮动方块(月亮块)

    它会根据时间交互有偏移, 因此你的冲刺不会直接撞上它; 它会往后退. 这带来了更大的 corner boost 余量, 以及由于它移动了也带来了机关加速. 非常好用(棒读).

    16. 水母

    扔开水母会给你一个反方向的 70 的加速. 这相当大了.

    17. 水面

    露出水面开始一直可以起跳, 最多可以跳九次, 获得九次 D40.

    18. 撞击交互

    只有从下方撞击不会让你跳起来, 因此速通尽量选择从下方撞. 但是如果没有办法做到, 那么可以用一个小跳来打断默认的跳跃. 在非常精确的情况下, 可以同时撞击方块和接触地面以恢复充能(1A ARB用到).

    19. 机制组合技巧

    • 抓角加速(Corner Boost)
      当没有撞墙就能抓墙的时候,抓墙跳可以给出 D40,-105 的速度; 如果在 4 帧内绕过墙角, 那么会保留这个速度.
      对于冰火墙的 CB 则必须用判定箱最下面的一行抓墙, 然后跳起把伤害箱移出冰火墙伤害箱的高度.
    • 反向抓角(Reverse Corner Boost)
      通过判定间隙或者绕墙机制绕过墙角后, 向墙的方向抓跳一下能获得 D-40,-105. 这可以用在
      • 冲刺打断
      • 保留大部分速度
      • 多一次机关加速
    • 延迟Ultra(Delayed Ultra)
      下斜冲被打断后, 在下一次落地会出现蹲姿, 横向速度变为 1.2 倍的情况. (但是有些时候不触发, 我不知道是什么原因.)
    • 双抓角加速(Double Corner Boost)
      如果速度足够低, 可以 CB 两次, 获得 D80.
    • demohyper
      蹲姿冲刺入平台然后做压身大跳.
      • 在常规只能得到 260 速度的地方得到 325.
      • 对于一些不蹲姿进不去的平台可以踩上去且恢复充能.
    • 多次机关加速
      • 对于站在上面的机关, 可以做反向压身大跳接一个跳, 然后在机关加速十帧内向斜下冲刺, 然后通过判定间隙绕过角做一个 Reverse Corner Boost.
      • 对于在旁边扒着的机关, 很多时候可以多次反向抓墙跳. 但是这个很玄学.
    • demodash咖啡
      咖啡跳就是绕过墙角踢跳.
      可以通过 demodash 绕过墙底, 然后在墙的另一面伸出头, 踢墙跳一下.
    • 减少爬墙的体力消耗
      可以中性抓跳 11 帧, 输入反方向离开墙面, 然后对着墙面方向抓跳. 这样和普通爬墙速度差不多, 但是减少一半体力消耗.
      同时, 因为要从墙外回到墙上, 会有一个速度, 方便接上 CB.
    • 落地同时保留向下的速度
      直观地看, 只要你不是被"拍"到地面上的, 那你可以利用判定间隙滑下平台边缘的角, 恢复充能, 同时保留了向下的速度. 更好的是, 在这个时候下仍然可以威利狼跳.

    20. 杂七杂八的东西

    • 有特殊的检查代码让人不能从被刺覆盖的平台上恢复充能.
  • 相关阅读:
    struts2(2.0.x到2.1.2版本)的核心和工作原理(转)
    关于Struts2通配符无效的说明
    contOS 网络配置
    INFORMATICA 开发规范
    Python tricks(1) -- 动态定义一个新变量
    MySQL connector c++使用笔记
    python使用set来去重碰到TypeError: unhashable type
    Redis 资料整理
    Ruby 安装和gem配置
    爱读书的犹太人
  • 原文地址:https://www.cnblogs.com/tmzbot/p/12318561.html
Copyright © 2020-2023  润新知