如何设计类似超级马里奥的游戏角色跳跃效果?
实现《超级马里奥》风格自然跳跃手感的优化方案
我想要实现类似《超级马里奥》的跳跃效果,但当前代码的跳跃表现不够自然,以下是我写的近似代码:
const SPEED = 300.0 const JUMP_VELOCITY = -300.0 const MAX_JUMP_FORCE = -600.0 const MAX_JUMP_TIME = 0.5 var jump_press_duration = 0.0 func _physics_process(delta): print_debug(velocity.y + jump_press_duration * gravity) # Add the gravity. if not is_on_floor(): velocity.y += gravity * delta ## Handle jump. #if Input.is_action_just_pressed("ui_accept") and is_on_floor(): #velocity.y = JUMP_VELOCITY if Input.is_action_just_pressed("ui_accept") and is_on_floor(): velocity.y = JUMP_VELOCITY jump_press_duration = 0 if Input.is_action_pressed("ui_accept") and not is_on_floor(): jump_press_duration += delta if jump_press_duration < MAX_JUMP_TIME: velocity.y += (MAX_JUMP_FORCE - JUMP_VELOCITY) * (delta / MAX_JUMP_TIME) # Get the input direction and handle the movement/deceleration. # As good practice, you should replace UI actions with custom gameplay actions. var direction = Input.get_axis("ui_left", "ui_right") if direction: velocity.x = direction * SPEED else: velocity.x = move_toward(velocity.x, 0, SPEED) move_and_slide()
原代码的核心问题
- 跳跃力叠加逻辑不合理:线性插值的方式无法还原马里奥"轻按小跳、长按大跳"的非线性手感,且未限制最大向上速度,容易导致跳跃速度失控。
- 重力与跳跃的处理顺序错误:先应用重力再处理跳跃,会让初始跳跃力被重力抵消一部分,导致起跳感偏软。
- 未处理跳键松开的情况:马里奥中松开跳键会立即停止额外升力,直接进入下落状态,原代码缺少该逻辑。
修改后的优化代码
const SPEED = 300.0 const BASE_JUMP_VELOCITY = -350.0 # 基础起跳速度 const MAX_JUMP_VELOCITY = -650.0 # 最大跳跃速度,实现强烈大跳效果 const JUMP_HOLD_ACCEL = -1200.0 # 按住跳键时的持续向上加速度 var is_holding_jump = false # 标记是否处于按住跳键状态 func _physics_process(delta): # 先处理水平移动 var direction = Input.get_axis("ui_left", "ui_right") if direction != 0: velocity.x = direction * SPEED else: velocity.x = move_toward(velocity.x, 0, SPEED * 2) # 提升地面减速幅度,还原马里奥干脆的停止手感 # 跳跃逻辑 if is_on_floor(): is_holding_jump = false # 落地时重置y轴速度,避免残留下落速度影响起跳 if velocity.y > 0: velocity.y = 0 else: # 先应用重力,再处理跳跃升力,符合物理逻辑顺序 velocity.y += gravity * delta # 按住跳键时持续施加升力,但不超过最大跳跃速度 if is_holding_jump and velocity.y > MAX_JUMP_VELOCITY: velocity.y += JUMP_HOLD_ACCEL * delta # 跳键按下/松开事件处理 if Input.is_action_just_pressed("ui_accept") and is_on_floor(): velocity.y = BASE_JUMP_VELOCITY is_holding_jump = true if Input.is_action_just_released("ui_accept"): is_holding_jump = false move_and_slide()
优化点说明
- 调整处理顺序:先处理水平移动,再处理跳跃与重力,贴合马里奥的物理反馈逻辑。
- 非线性跳跃手感:通过持续施加固定加速度实现长按跳更高的效果,同时限制最大向上速度,避免失控。
- 加入跳键松开逻辑:松开跳键后立即停止额外升力,还原马里奥的跳跃反馈。
- 地面减速优化:提升地面减速系数,让角色停止动作更干脆,贴近原版游戏手感。
内容的提问来源于stack exchange,提问作者user23783268
相关产品推荐
相关产品推荐

