使用 Smart Shape 构建 OrbitRun | 第 2 部分:控制飞行
Logo

飞船会移动了,但你还不能控制它。按住屏幕时,让向下的拉力变强;松开时,再减弱拉力。飞行手感调好后,添加距离分数和 90 秒倒计时。

从 第 1 部分的项目开始,或从检查点资源包中打开 OrbitRun-05-launch.tap。以下所有行为都属于 Skimmer。将每个编号课程放在各自带注释的区域中,并在行与列之间留出空隙。

重建后的 OrbitRun 项目全新游戏录屏

在示意图中,REUSE 表示使用你已经添加的行为。如需回顾连接行为的手势,请参阅第 1 部分中的行为连接指南。点击图片可全尺寸查看。

6. 按住俯冲,松开滑翔

飞船朝下坡飞行时按住屏幕。额外的重力会帮助它加速。在山坡转向上坡时松开,飞船就能借助这股速度爬升。

示意图:在下坡路段按住,在山坡转为上坡时松开

首先,让游戏运行时按下屏幕能够改变重力。

动画连接指南:按住俯冲

以静态图片打开完成后的示意图。

  1. 添加名为 Touch 的 While Touching。
  2. 添加名为 Touch State 的 Get Attribute。将 Touch 底部一个空闲的白色圆形连接到 Touch State。
  3. 添加名为 Touch Running 的 If。将 Touch State 底部一个空闲的白色圆形连接到 Touch Running。
  4. 添加名为 Dive 的 Set Gravity。将 Touch Running 底部(true)圆形连接到 Dive。
  5. 添加名为 Dive Cue 的 Change Label。将 Touch Running 底部(true)圆形连接到 Dive Cue。

使用以下设置:

  • Touch: Input Plane;Touch Anywhere 设为 Off;Absorbs Touch 设为 On。让它从场景开始时就持续监听。
  • Touch State: Skimmer;属性 runState。
  • Touch Running: First value 取自 Touch State 的 Attribute Value;比较方式 Equals;second value 为 running。
  • Dive: Skimmer;重力类型 Object;X 0,Y −32。
  • Dive Cue: Cue;文本 DIVING / RELEASE AS THE HILL TURNS UP。

Dive 和 Dive Cue 都直接连接到 Touch Running 底部的连接器。右侧的 false 连接器留空。

将状态拖入 If

选择接收行为,将源输出拖到 First value (A),选择 attributeValue,并检查生成的引用

松开后,First value (A) 中会出现 Touch State · attributeValue。将比较方式设为 Equals;second value 设为 running。

松开手指后,应恢复较弱的重力。复用第 1 部分中的 Release。

动画连接指南:松开滑翔

以静态图片打开完成后的示意图。

  1. 添加名为 Touch Ended 的 Stopped Touching。
  2. 添加名为 Release State 的 Get Attribute。将 Touch Ended 底部一个空闲的白色圆形连接到 Release State。
  3. 添加名为 Release Running 的 If。将 Release State 底部一个空闲的白色圆形连接到 Release Running。
  4. 复用 Release。将 Release Running 底部(true)圆形连接到 Release。
  5. 复用 Glide Cue。保留它已有的来自 Release 的执行连接;动画中为便于参考重新绘制了这条连线。不要再添加第二条连接。

使用以下设置:Touch Ended 的目标设为 Input Plane,Touch Anywhere 设为 Off、Absorbs Touch 设为 On、Check Boundaries 设为 Off。Release State 读取 Skimmer 的 runState。Release Running 将该 Attribute Value 与 running 比较。

将已有的 Release 和 Glide Cue 移到 Release Running 下方。保留它们已有的连接和之前的启动连接。Release 仍然将对象重力设为 X 0、Y −12;Glide Cue 仍然显示滑翔提示。

在开放的游戏区域启动并按住,然后抬起手指。提示应在 DIVING 和 GLIDING 之间切换。请避开音乐按钮进行测试。在标题屏幕上按住不应触发俯冲。

如果触摸没有反应,请检查 Input Plane 是否位于 Scene UI 上、在按钮后方、覆盖整个屏幕,并且可见且不透明度为 0%。如果在最初触摸点以外松开时没有反应,请检查 Check Boundaries 是否设为 Off。

这两项触摸检查都会在改变重力前读取 runState。只有它的值为 running 时才能俯冲。添加结束逻辑后,相同的检查也能让飞船保持静止。

7. 让飞船朝向速度方向

飞船下落时应朝下,爬升时应朝上。启动一个重复计时器来读取它的速度。稍后你还会用同一个速度读数,帮助飞船从缓慢着陆中恢复。

在检查任一速度限制之前,先读取速度。两个检查都从 Velocity 开始。

动画连接指南:先检查速度,再进行调整

以静态图片打开完成后的示意图。

  1. 复用 Generate。
  2. 添加名为 Flight Tick 的 Timer。将 Generate 底部一个空闲的白色圆形连接到 Flight Tick。
  3. 添加名为 Velocity 的 Get Velocity。将 Flight Tick 底部一个空闲的白色圆形连接到 Velocity。
  4. 添加名为 Slow Check 的 If。将 Velocity 底部一个空闲的白色圆形连接到 Slow Check。
  5. 添加名为 Fast Check 的 If。将 Velocity 底部一个空闲的白色圆形连接到 Fast Check。
  6. 添加名为 Assist 的 Set Velocity。将 Slow Check 底部(true)圆形连接到 Assist。
  7. 添加名为 Speed Limit 的 Set Velocity。将 Fast Check 底部(true)圆形连接到 Speed Limit。

使用以下设置:

  • Flight Tick: 0.05 秒;Repeat Forever 设为 On;Start Immediately 设为 Off。Generate 的触发器仍为 Ready。
  • Velocity: 目标为 Skimmer。
  • Slow Check: Velocity 的 X Velocity < 8。Assist: X 12,Maintain X 设为 Off,Maintain Y 设为 On。
  • Fast Check: Velocity 的 X Velocity > 42。Speed Limit: X 42,Maintain X 设为 Off,Maintain Y 设为 On。

将检查放在其效果上方。Slow Check 和 Fast Check 是 Velocity 下的两个独立分支。

将 X 速度拖入检查

选择接收行为,将源输出拖到 First value (A),选择 velocity_x,并检查生成的引用

松开后,First value (A) 中会出现 Velocity · velocity_x。将比较方式设为 Is Less Than;second value 设为 8。

以下是在实际编辑器中的相同拖动操作。先选择 Slow Check。将 Velocity 的绿色输出图标拖到第一个输入,并选择 velocity_x。

录制的编辑器手势:将 Velocity 拖入 Slow Check

Slow Check 中完成后的输入引用

参阅 Sharing Values Between Behaviors 和 If。输入字段内的绿色按钮会创建 Change Input Field 行为;拖动时,请使用源行为上的输出图标。

用同一个速度读数来计算飞船的角度。

动画连接指南:朝运动方向转向

以静态图片打开完成后的示意图。

  1. 复用 Velocity。
  2. 添加名为 Angle Moving 的 If。将 Velocity 底部一个空闲的白色圆形连接到 Angle Moving。
  3. 添加名为 Slope Ratio 的 Divide Values。将 Angle Moving 底部(true)圆形连接到 Slope Ratio。
  4. 添加名为 Flight Angle 的 Math Function。将 Slope Ratio 底部一个空闲的白色圆形连接到 Flight Angle。
  5. 添加名为 Clockwise Angle 的 Multiply Values。将 Flight Angle 底部一个空闲的白色圆形连接到 Clockwise Angle。
  6. 添加名为 Rotate 的 Rotate To Angle。将 Clockwise Angle 底部一个空闲的白色圆形连接到 Rotate。

使用以下设置:

  • Angle Moving: Velocity 的 X Velocity > 0.1。
  • Slope Ratio: 第一个数值 = Velocity 的 Y Velocity;第二个数值 = Velocity 的 X Velocity。
  • Flight Angle: 选择 Arctangent,输入 Slope Ratio 的结果。
  • Clockwise Angle: 第一个数值 = Flight Angle 的结果;第二个数值 = −1。
  • Rotate: 目标为 Skimmer;角度 = Clockwise Angle 的结果。设置较短的持续时间,让转向平滑。

引用数值时,请使用绿色输出拖动操作。不要在数值字段中输入公式。使用这些行为进行计算,再将它们的结果放入接收字段。

不触摸屏幕,连续飞过几座山坡。飞船在下坡时应机头朝下,爬坡时机头朝上。即使速度减慢,也应继续移动。

角度由 atan(vy / vx) 得出。先检查 X 速度可避免除数接近零。乘以 −1 可让结果按照 hyperPad 使用的旋转方向调整。

这个计算假设飞船向前移动。如果要将它改为向后飞行,还需要考虑方向,可使用 atan2,或针对每个象限分别检查。

辅助加速和速度上限只改变水平速度。保持 Y 不变,可保留当前的跳跃或下落状态。42 是 X 速度上限,因此在陡峭俯冲时,稍后显示的总速度可能超过 42。

8. 将世界坐标转换为分数

你的分数用于衡量飞船在水平方向上飞行了多远。用它当前的世界 X 坐标减去起始 X 坐标即可。镜头可以随意移动。

此连接会读取飞船的位置,并将它转换为距离标签。

动画连接指南:将位置转换为距离

以静态图片打开完成后的示意图。

  1. 复用 Generate。
  2. 添加名为 Hud Tick 的 Timer。将 Generate 底部一个空闲的白色圆形连接到 Hud Tick。
  3. 添加名为 Position 的 Get Position。将 Hud Tick 底部一个空闲的白色圆形连接到 Position。
  4. 添加名为 Distance Value 的 Subtract Values。将 Position 底部一个空闲的白色圆形连接到 Distance Value。
  5. 添加名为 Distance Round 的 Round Number。将 Distance Value 底部一个空闲的白色圆形连接到 Distance Round。
  6. 添加名为 Distance Text 的 Combine Text。将 Distance Round 底部一个空闲的白色圆形连接到 Distance Text。
  7. 添加名为 Distance Label 的 Change Label。将 Distance Text 底部一个空闲的白色圆形连接到 Distance Label。

使用以下设置:

  • Hud Tick: 0.2 秒;Repeat Forever 设为 On;Start Immediately 设为 Off。
  • Position: Skimmer;Screen Coordinates 设为 Off。
  • Distance Value: 第一个数值 = Position 的 X Position;第二个数值 = 8。
  • Distance Round: 使用 Distance Value 的结果;模式设为 Floor。
  • Distance Text: 第一个输入 = Distance Round 的结果;第二个输入 = m;Space 设为 On。
  • Distance Label: 目标为 Distance;文本 = Distance Text 的 Combined Text。

Hud Tick 设置

在计算中使用世界 X 坐标

选择接收行为,将源输出拖到 First number (A),选择 position_x,并检查生成的引用

松开后,First number (A) 中会出现 Position · position_x。第二个数值保持为 8:当前 X 减去起始 X。

将速度显示作为单独的连接添加到 Hud Tick。

动画连接指南:添加第二个 HUD 分支

以静态图片打开完成后的示意图。

  1. 复用 Hud Tick。
  2. 添加名为 Speed Round 的 Round Number。将 Hud Tick 底部一个空闲的白色圆形连接到 Speed Round。
  3. 添加名为 Speed Text 的 Combine Text。将 Speed Round 底部一个空闲的白色圆形连接到 Speed Text。
  4. 添加名为 Speed Label 的 Change Label。将 Speed Text 底部一个空闲的白色圆形连接到 Speed Label。

使用以下设置:Speed Round 读取 Velocity 的 Speed 输出,并使用 Floor。Speed Text 将 Speed Round 的结果与 m/s 组合,Space 设为 On。Speed Label 的目标为 Speed,读取 Speed Text 的 Combined Text。

将 Velocity 的数据拖到 Speed Round 的数值字段中。执行连接来自 Hud Tick,如示意图所示。读取 Velocity 的数值不需要从 Velocity 到 Speed Round 添加执行连线。

启动并观察 Distance 从接近零开始增加。当世界 X 坐标到达 108 m 时,显示的距离应为 100 m,因为飞船的起始位置是 X 8 m。镜头移动不应重置分数。

Hud Tick 会读取 Velocity 的最新结果。它每秒更新标签五次,而飞行检查的频率更高。你可以降低显示更新频率,而不影响飞船的物理运动。

Set Label 参考文档介绍了此标签更改行为(在此编辑器中名为 Change Label)。

9. 从 90 秒开始倒计时

和其他计时器一样,从 Ready 启动秒数计时器。

动画连接指南:制作倒计时

以静态图片打开完成后的示意图。

  1. 复用 Generate。
  2. 添加名为 Seconds Tick 的 Timer。将 Generate 底部一个空闲的白色圆形连接到 Seconds Tick。
  3. 添加名为 Seconds 的 Add Values。将 Seconds Tick 底部一个空闲的白色圆形连接到 Seconds。
  4. 添加名为 Remaining 的 Subtract Values。将 Seconds 底部一个空闲的白色圆形连接到 Remaining。
  5. 添加名为 Clock Text 的 Combine Text。将 Remaining 底部一个空闲的白色圆形连接到 Clock Text。
  6. 添加名为 Clock Label 的 Change Label。将 Clock Text 底部一个空闲的白色圆形连接到 Clock Label。

使用以下设置:Seconds Tick 设为 1 秒;Repeat Forever 设为 On;Start Immediately 设为 Off。Seconds 将 1 加到它上一次的结果,初始值为 0。Remaining 用 90 减去 Seconds 的结果。Clock Text 将 Remaining 的结果与 s 组合,Space 设为 On。Clock Label 的目标为 Clock,并使用 Clock Text 的 Combined Text。

使用行为自身的结果

选择接收行为,将源输出拖到 First number (A),选择 final value,并检查生成的引用

松开后,First number (A) 中会出现 Seconds · final value。第二个数值保持为 1。初始结果为 0。

Seconds 在第一个输入中使用自身的结果

要引用行为自身,请保持选中 Seconds,并将 Seconds 自己的绿色输出图标拖到它的第一个数值字段中。选择它的结果(在输出引用中显示为 final value)。将第二个数值设为 1。第一次计时器触发时,时钟会从 90 s 变为 89 s。

有关重复和立即启动设置,请参阅 Timer。

三个更新间隔及其各自用途

在标题屏幕上等待几秒。时钟应保持在 90 s。启动后,时钟应每秒倒数一次。请在倒计时到零之前结束这次测试;你会在第 3 部分中添加结束逻辑。

在这个原型中,你通过计数 Timer 事件来追踪经过的秒数。如果你的游戏需要在中断期间也保持精确计时,请改为从时钟读取经过的时间。Timer 事件可能会延迟触发。

打造自己的手感

每次实验只改一个数值,然后重新游玩:

  • 将 Dive 重力从 −32 改为 −24。按住时的力度是否减弱?
  • 将辅助速度从 12 改为 10。着陆不佳时,游戏是否更难?
  • 将 Hud Tick 从 0.2 改为 0.5 秒。观察显示变得不那么平滑,但飞船仍正常移动。

进入第 3 部分:世界变化与重新游玩前,请恢复教程中的数值。如果你的版本有所不同,请与检查点 09-countdown 对照。