player脚本重写以及提升角色控制手感

Heart Lv462

今天对 Player 脚本进行了完整重写,目标是让角色的移动、跳跃手感更加丝滑,并加入两个经典的动作游戏机制——Coyote Time(土狼时间)Jump Buffer(跳跃缓冲)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
## 新版代码


extends CharacterBody2D

@onready var sprite_2d: Sprite2D = $Sprite2D
@onready var animation_player: AnimationPlayer = $AnimationPlayer

const speed = 200
@export var JUMP_VELOCITY = -320
const floor_acceleration := speed / 0.2
const air_acceleration := speed / 0.02

@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 模式。
  • 动画拖影:项目>项目设置>物理>通用>物理插值打开,然后把物理抖动调为0
  • Title: player脚本重写以及提升角色控制手感
  • Author: Heart
  • Created at : 2025-08-10 02:01:15
  • Updated at : 2025-12-31 20:54:57
  • Link: https://yhalo-wyh.github.io/2025/08/10/player-gd重写以及提升角色控制手感/
  • License: This work is licensed under CC BY-NC-SA 4.0.
Comments