跳跃手感:8 个参数,和它们为什么这样取值
土狼时间、跳跃缓冲、可变跳跃高度、上升下降重力差、顶点悬停、落地压缩、尘土与停顿——每个参数给一个起始值,并解释它解决的是什么问题。
「手感」不是玄学,它是一串可以量化的宽容度。玩家按下跳跃键的那一刻,输入是离散的,物理是连续的,中间那层翻译决定了游戏跟不跟手。
下面 8 个参数是像素猫小屋最终采用的数值,来自三十多次试玩调整。它们不是标准答案,但每一个都对应一个具体的失败体验。
参数表
| 参数 | 取值 | 解决的问题 |
|---|---|---|
| 土狼时间 | 0.10 s | 走出平台边缘后仍能起跳 |
| 跳跃缓冲 | 0.12 s | 落地前按下跳跃,落地瞬间自动起跳 |
| 起跳速度 | -330 px/s | 跳跃高度约 56 px,等于 3.5 个猫身高 |
| 上升重力 | 980 px/s² | 上升过程偏轻 |
| 下降重力 | 1500 px/s² | 下落更快,避免发飘 |
| 松键截断 | 速度乘 0.45 | 点按小跳,长按大跳 |
| 顶点悬停 | 0.08 s,重力乘 0.6 | 最高点停留,给玩家判断时间 |
| 落地停顿 | 0.06 s | 落地瞬间的重量感 |
为什么是这几个数
土狼时间 0.1 秒大约是 6 帧。低于 0.05 秒玩家感知不到,高于 0.15 秒会出现「明明已经掉下去却又跳起来」的诡异感。
跳跃缓冲 0.12 秒比土狼时间稍长,因为玩家的容错心理是「我按了就该算」。这两个值不需要相等,但差距不要超过 2 倍。
下降重力是上升的 1.5 倍,这是最划算的一条:上升慢让玩家看清落点,下降快让落地干脆。多数游戏落在 1.2 到 2.0 之间,超过 2.2 会像掉进水里。
代码:一次写对
extends CharacterBody2D
@export var jump_velocity := -330.0
@export var gravity_up := 980.0
@export var gravity_down := 1500.0
@export var coyote_time := 0.10
@export var jump_buffer := 0.12
@export var apex_threshold := 60.0
@export var apex_gravity_scale := 0.6
var coyote := 0.0
var buffer := 0.0
func _physics_process(delta: float) -> void:
if is_on_floor():
coyote = coyote_time
else:
coyote = maxf(coyote - delta, 0.0)
if Input.is_action_just_pressed("jump"):
buffer = jump_buffer
else:
buffer = maxf(buffer - delta, 0.0)
if buffer > 0.0 and coyote > 0.0:
velocity.y = jump_velocity
buffer = 0.0
coyote = 0.0
squash(0.8, 1.2)
# 松键截断:只在上升段生效
if Input.is_action_just_released("jump") and velocity.y < 0.0:
velocity.y *= 0.45
var g := gravity_up if velocity.y < 0.0 else gravity_down
if absf(velocity.y) < apex_threshold:
g *= apex_gravity_scale
velocity.y += g * delta
velocity.y = minf(velocity.y, 900.0)
move_and_slide()
if is_on_floor() and velocity.y >= 0.0:
squash(1.15, 0.85)注意两个细节:松键截断只作用在上升段,否则会把下落也截断;顶点悬停用「接近 0 的速度」判断,而不是固定高度,这样小跳和大跳都有悬停。
视觉:手感的一半在动画里
数值只解决跟手,重量感要靠动画补:
- 起跳:纵向拉伸 1.2 倍,横向压缩 0.85,持续 0.08 秒
- 下落:轻微拉长,随速度增加
- 落地:先压扁到 0.8,再 0.1 秒回弹到 1.05,最后回 1
- 尘土:落地时在脚下生成 3 到 5 个粒子,向左上、正上、右上散开,寿命 0.25 秒
- 相机:落地时向下偏移 2 px,0.12 秒回位;不要做整屏震动,会很廉价
两个反直觉的结论
不要给跳跃加加速度曲线。 很多人想在起跳瞬间做缓入,结果玩家觉得按键有延迟。起跳必须是瞬时速度赋值,宽容度交给缓冲和截断。
不要做二段跳,除非关卡为它设计。 二段跳会让所有平台间距失去意义,第一版我加了,第二天就删了——它让土狼时间变得没必要,也让坠落不再有惩罚。
怎么验证
把游戏给你自己玩 10 分钟,只看一件事:有没有哪次死亡你觉得「不是我的错」? 有,就是某个参数还不够宽容。记录下来,一次只调一个,调完再玩 10 分钟。