如何解决位置插补引起的抖动

时间:2019-02-08 18:15:52

标签: python pygame linear-interpolation

我想在一段时间内插入对象的位置,我正在使用pygame。

当游戏要将对象移动到某个位置时,它将调用interpolate_position并指定其所需的位置以及插入所需的时间。 update在基本游戏循环中被调用。 这段代码是GameObject类的一部分:

    def update(self, dt):
        if self.is_lerping:
            self.update_interpolate(dt)

    def update_interpolate(self, dt):
        if self.start_lerp - self.total_lerp_time <= 2 * dt:
            val = dt / (self.total_lerp_time - self.start_lerp)
            val = val if 0 < val < 1 else 1
            self.position = self.position.lerp(self.lerp_goal, val)
            self.start_lerp += dt
        else:
            self.position = self.lerp_goal
            self.is_lerping = False

    def interpolate_position(self, pos, lerp_time):
        self.is_lerping = True
        self.total_lerp_time = lerp_time
        self.start_lerp = 0
        self.lerp_goal = Vector2(pos)

更新称为:

AVERAGE_DELTA_MILLIS = round(float(1000) / 60, 4)
while True:
    before_update_and_render = self.clock.get_time()
    delta_millis = (update_duration_millis + sleep_duration_millis) / 1000            
    o.update(delta_millis)  #  Updates the object
    update_duration_millis = (self.clock.get_time() - before_update_and_render) * 1000
    sleep_duration_millis = max([2, AVERAGE_DELTA_MILLIS - update_duration_millis])
    time.sleep(sleep_duration_millis / 1000)  # Sleeps an amount of time so the game will be 60 fps

我的代码有时可以正常工作,但是有时对象应该静止不动,则它在某个方向上来回移动一个像素。我的主要猜测是某种舍入误差。我该怎么做才能解决此问题?预先感谢。

2 个答案:

答案 0 :(得分:1)

如果要将val限制在[0,1]范围内,那么我更喜欢使用min()max()

val = max(0, min(val, 1))

self.start_lerp不断增加,直到“达到” self.total_lerp_time
因此条件self.start_lerp - self.total_lerp_time <= 2 * dt是错误的解决方法。

必须为:

if self.total_lerp_time - self.start_lerp > 2 * dt:
    # [...]

或者甚至更好地使用内置函数abs(),该函数甚至适用于负值:

if abs(self.total_lerp_time - self.start_lerp) > 2 * dt:
    # [...]

答案 1 :(得分:0)

发生错误是因为目标位置和当前位置相同。我添加了一张支票以防止这种情况,现在一切正常。