@onready var coyotetimer: Timer = $coyotetimer @onready var jumprequesttimer: Timer = $jumprequesttimer
func _unhandled_input(event: InputEvent) -> void: if event.is_action_pressed("jump"): jumprequesttimer.start() if event.is_action_released("jump"): jumprequesttimer.stop() if velocity.y < JUMP_VELOCITY / 2.0: velocity.y = JUMP_VELOCITY / 2.0
var gravity := ProjectSettings.get("physics/2d/default_gravity") as float
func _physics_process(delta: float) -> void: var direction := Input.get_axis("left", "right") var acceleration := floor_acceleration if is_on_floor() else air_acceleration velocity.x = move_toward(velocity.x, direction * speed, acceleration * delta) velocity.y += gravity * delta var can_jump := is_on_floor() or coyotetimer.time_left > 0 var should_jump := can_jump and jumprequesttimer.time_left > 0 if should_jump: velocity.y = JUMP_VELOCITY coyotetimer.stop() jumprequesttimer.stop() if is_on_floor(): if is_zero_approx(direction) and is_zero_approx(velocity.x): animation_player.play("idle") else: animation_player.play("run") elif velocity.y < 0: animation_player.play("jump") else: animation_player.play("fall") if not is_zero_approx(direction): sprite_2d.flip_h = direction < 0 var was_on_floor := is_on_floor() move_and_slide() if is_on_floor() != was_on_floor: if was_on_floor and not should_jump: coyotetimer.start() else: coyotetimer.stop()
核心改动
1. 引入 土狼时间(Coyote Time)
在玩家离开地面的一小段时间内,仍然可以触发跳跃。
这样玩家即使在边缘稍微晚按跳跃,也能成功起跳,容错率更高。
通过 coyotetimer 计时器实现,时间可调(如 0.1~0.2 秒)。
2. 加入 跳跃缓冲
玩家在落地前的短时间按下跳跃,会在落地瞬间自动起跳。
用 jumprequesttimer 记录按键请求时间。
3. 加入 空中转身
direction > 0(向右移动) → flip_h = false → 精灵保持朝右
direction < 0(向左移动) → flip_h = true → 精灵水平翻转朝左
空中也生效,因为它不依赖 is_on_floor(),所以在跳跃/下落时依旧可以转身
4. 可变跳跃高度
松开跳跃键时,如果角色还在上升阶段,就将竖直速度减半,形成短跳效果。
调试与踩坑
整数除法警告:在比较 JUMP_VELOCITY / 2 时需要写成 2.0 才不会丢失小数。
定时器路径:$coyotetimer 和 $jumprequesttimer 必须在场景树里存在并设置好 One Shot 模式。