You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Godot平台跳跃游戏:玩家遇敌未下落反而跳跃问题求助

Godot移动端平台跳跃游戏死亡逻辑异常排查

问题描述

首次使用Godot开发移动端平台跳跃游戏,希望实现玩家碰撞敌人后下落死亡的效果,但尝试多日始终存在异常:在dying函数中设置velocity.y=-500后,玩家并未下落,反而出现类似跳跃的行为。

玩家代码

extends KinematicBody2D

onready var rayS = get_node("rayL")
onready var rayD = get_node("rayR")
onready var sprite = get_node("AnimatedSprite")

var alive = true

signal dead

const WALK_FORCE = 600
const WALK_MAX_SPEED = 300
const STOP_FORCE = 1300
const JUMP_SPEED = 700
const gravity = 1100.0

var velocity = Vector2()

func _physics_process(delta):
    var force = Vector2(0, gravity)
    
    var walk_left = Input.is_action_pressed("move_left") and alive
    var walk_right = Input.is_action_pressed("move_right") and alive
    var jump = Input.is_action_pressed("jump") and alive
    # Horizontal movement code. First, get the player's input.
    var walk = WALK_FORCE * (Input.get_action_strength("move_right") - Input.get_action_strength("move_left"))
    # Slow down the player if they're not trying to move.
    if abs(walk) < WALK_FORCE * 0.2:
        # The velocity, slowed down a bit, and then reassigned.
        velocity.x = move_toward(velocity.x, 0, STOP_FORCE * delta)
    else:
        velocity.x += walk * delta
    # Clamp to the maximum horizontal movement speed.
    velocity.x = clamp(velocity.x, -WALK_MAX_SPEED, WALK_MAX_SPEED)

    # Vertical movement code. Apply gravity.
    velocity.y += gravity * delta

    # Move based on the velocity and snap to the ground.
    velocity = move_and_slide_with_snap(velocity, Vector2.DOWN, Vector2.UP)

    # Check for jumping. is_on_floor() must be called after movement code.
    if is_on_floor() and Input.is_action_just_pressed("jump"):
        jumping()
    
    var on_floor = rayL.is_colliding() or rayR.is_colliding()
    
    if walk_right:
        sprite.set_flip_h(false)
    if walk_left:
        sprite.set_flip_h(true)
    
    if (walk_left or walk_right) and on_floor:
        sprite.play()
    elif (walk_left or walk_right):
        sprite.stop()
        sprite.set_frame(3)
    else:
        sprite.stop()
        sprite.set_frame(1)
    
    if position.y > 900: dying()


func _on_Area2D_body_entered(body):
    if not alive: return
    jumping()
    body.destroy()

func jumping():
    velocity.y = -JUMP_SPEED
    

func _on_Area2D2_body_entered(body):
    if not alive: return
    dying()

func dying():
    if not alive: return
    alive = false
    velocity.y = -500
    collision_mask -= 2
    emit_signal("dead")

问题原因与修复方案

核心问题

  1. 死亡后仍执行完整移动逻辑:即使alive设为false,_physics_process中依然会执行水平移动、地面吸附(move_and_slide_with_snap)等逻辑,干扰死亡下落行为。
  2. 错误的速度方向:velocity.y=-500是向上的速度,和下落需求相反,后续重力叠加需要时间抵消向上速度,期间会出现类似跳跃的视觉效果。
  3. 变量名笔误:代码中定义了rayS和rayD,但实际使用的是rayL和rayR,可能导致地面检测异常。

修复步骤

  1. 隔离死亡状态逻辑:在_physics_process开头添加判断,死亡时仅处理下落,跳过其他移动逻辑:
    func _physics_process(delta):
        if not alive:
            velocity.y += gravity * delta
            # 取消地面吸附,用普通move_and_slide处理下落
            velocity = move_and_slide(velocity, Vector2.UP)
            return
        # 原有的移动、跳跃、动画逻辑继续执行
    
  2. 修正死亡时的速度设置:将dying中的向上速度改为向下,或直接让重力自然驱动下落:
    func dying():
        if not alive: return
        alive = false
        velocity.y = 500  # 设置向下初始速度,加速下落
        collision_mask -= 2
        emit_signal("dead")
    
  3. 修正变量名笔误:统一地面检测射线的变量名,避免潜在错误:
    onready var rayL = get_node("rayL")
    onready var rayR = get_node("rayR")
    

内容的提问来源于stack exchange,提问作者user21243186

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 09:56:21