2

我正在尝试使用 GDScript 在 Godot 中创建一个可播放的精灵。我让我的角色左右移动,然后在没有输入时停止。

但是,我希望精灵放慢速度,而不是完全停止。我该怎么写?

extends KinematicBody2D

var motion = Vector2()



func _physics_process(delta):

if Input.is_action_pressed("ui_right"):
    motion.x = 250


elif Input.is_action_pressed("ui_left"):
    motion.x = -250

else:
    motion.x = 0

move_and_slide(motion)

pass
4

2 回答 2

1

好的,我想通了:

extends KinematicBody2D

var motion = Vector2()

func _physics_process(delta):

    if Input.is_action_pressed("ui_right"):
        motion.x = 250
    
    
    elif Input.is_action_pressed("ui_left"):
        motion.x = -250
    
    else:
        motion.x = motion.x * .9
    
    move_and_slide(motion)
于 2019-02-04T21:38:24.287 回答
0

一个非常简单的方法是在每次更新时降低速度——这个概念是从物理阻力中借来的。

extends KinematicBody2D
    var motion = Vector2()

func _physics_process(delta):
    if Input.is_action_pressed("ui_right"):
        motion.x = 250
    elif Input.is_action_pressed("ui_left"):
        motion.x = -250
    else:
        motion.x *= 0.95 # slow down by 5% each frame - play with this value
                         # i.e. make it dependent on delta to account for different fps
                         #      or slow down faster each frame
                         #      or clamp to zero under a certain threshold

    move_and_slide(motion)
    pass

同样,这非常简单。如果您想提供某些保证(例如播放器应该在 6 帧后完全停止),尤其是在处理未锁定的 fps 时,调整拖动值可能会非常挑剔。

在这种情况下,不要使用单个motion向量,而是使用 alast_motion和 atarget_motion向量并在它们之间进行相应的插值,以获得每帧的当前motion向量(您也可以这样做以进行加速)。这需要您考虑状态转换,例如“当玩家停止按下按钮时”,启动计时器以跟踪插值的开始帧和目标帧之间的进度等......您选择什么样的插值函数将影响如何对玩家的运动感觉反应灵敏或迟缓。

这是使用线性插值在 0.2 秒内减速的示例:

enum MotionState {IDLE, MOVING, DECELERATING}

extends KinematicBody2D
    var state = IDLE
    var last_motion = Vector2()
    var time_motion = 0.0

func _physics_process(delta):
    var motion = Vector2();
    if Input.is_action_pressed("ui_right"):
        motion.x = 250
        state = MOVING
        last_motion = motion
    elif Input.is_action_pressed("ui_left"):
        motion.x = -250
        state = MOVING
        last_motion = motion
    elif state == IDLE
        motion.x = 0
    else:
        if state == MOVING:
            # start a smooth transition from MOVING through DECELERATING to IDLE
            state = DECELERATING
            # last_motion already holds last motion from latest MOVING state
            time_motion = 0.2
        # accumulate frame times
        time_motion -= delta
        if time_motion < 0.0:
            # reached last frame of DECELERATING, transitioning to IDLE
            state = IDLE
            motion.x = 0
        else:
            var t = (0.2 - time_motion) / 0.2 # t goes from 0 to 1
            # we're linearly interpolating between last_motion.x and 0 here
            motion.x = (1 - t) * last_motion.x

    move_and_slide(motion)
    pass

线性减速会感觉不对,但您可以轻松地将其替换为任何其他功能,例如尝试三次以更快地减速,从而更快地响应减速:motion.x = (1 - (t * t * t)) * last_motion.x

于 2019-02-04T22:21:19.077 回答