You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Godot 4.1角色移动仅少量像素且动画仅播放第一帧的问题求助

Godot 4.1角色移动仅少量像素且动画仅播放第一帧的问题求助

嘿,我看了你的代码和问题描述,马上就发现两个核心问题啦,咱们一步步来解决:

问题1:角色只移动少量像素的根源

你现在用的是Input.is_action_just_pressed()来检测按键,这个函数只会在按键被按下的那一帧返回true,也就是说每次按方向键,角色只在那一帧移动一下,之后就不动了,自然只能挪几像素。哪怕调大speed,也只是让这一帧的移动距离变大,看起来就像“跳着走”,完全没有平滑移动的效果。

正确的做法应该用Input.is_action_pressed(),这个函数会在按键按住的每一帧都返回true,这样角色就能持续移动啦。

问题2:动画只播放第一帧的原因

同样因为is_action_just_pressed()的问题,只有按键按下的那一帧会触发$AnimatedSprite2D.play(),之后的帧因为没检测到“刚按下”的动作,动画就停在第一帧了。改成持续检测按键状态后,动画就能正常循环播放了。

另外还有个小细节:你的动画切换逻辑放在了velocity处理之后,调整顺序能避免出现判断逻辑的小问题。

修改后的完整代码

extends Area2D

signal hit

@export var speed = 400  # 这里建议用400左右的数值,4000确实太大啦

var screen_size # Size of the game window.

func _ready():
    screen_size = get_viewport_rect().size
    # hide()

func _process(delta):
    var velocity = Vector2.ZERO #The player's movement vector.

    # 把is_action_just_pressed改成is_action_pressed
    if Input.is_action_pressed("move_down"):
        velocity.y += 1
    if Input.is_action_pressed("move_up"):
        velocity.y -= 1
    if Input.is_action_pressed("move_right"):
        velocity.x += 1
    if Input.is_action_pressed("move_left"):
        velocity.x -= 1

    if velocity.length() > 0:
        velocity = velocity.normalized() * speed
        $AnimatedSprite2D.play()
        
        # 调整动画切换逻辑到这里,确保每次有移动时都能正确切换动画
        if velocity.x != 0:
            $AnimatedSprite2D.animation = "walk"
            $AnimatedSprite2D.flip_v = false
            $AnimatedSprite2D.flip_h = velocity.x < 0
        elif velocity.y != 0:
            $AnimatedSprite2D.animation = "up"
            $AnimatedSprite2D.flip_v = velocity.y > 0
    else:
        $AnimatedSprite2D.stop()

    position += velocity * delta
    position = position.clamp(Vector2.ZERO, screen_size)

func _on_body_entered(body):
    hide() #Player dissappears after being hit.
    hit.emit()
    # Must be deferred as we can't change physics properties on a physics callback.
    $CollisionShape2D.set_deferred("disabled", true)

func start(pos):
    position = pos
    show()
    $CollisionShape2D.disabled = false

额外提示

  • 记得检查你的AnimatedSprite2D的动画是否设置了循环播放(在动画编辑器里勾选Loop选项),不然就算修复了代码,动画播完一次也会停在最后一帧。
  • speed设为400是比较合理的2D游戏移动速度,4000的话移动速度会快到离谱,角色瞬间就飞出屏幕啦。

备注:内容来源于stack exchange,提问作者jamyandy_1500

火山引擎 最新活动