【问题标题】:pygame moving fatser in one direction than another [duplicate]pygame在一个方向上比另一个方向移动得更快[重复]
【发布时间】:2021-11-13 10:22:30
【问题描述】:

我目前正在制作一个基于图块的平台游戏并为其编写“引擎”。我很远,但最近注意到玩家向左移动比向右移动更快,没有明显的原因。我检查了速度,但它按预期限制在-5.55.5 之间。在检查最后一个位置和当前位置之间的距离时,它是可见的。向右移动时,控制台输出的增量位置约为3(“约”是因为我根据增量时间进行移动,所以当电脑运行得更快时它会有所不同),但是当向左移动时,它表示差异是@ 987654324@。这是一个常见的错误吗?我尝试在负时将负速度限制在较低的水平,但这是一个非常笨拙的解决方案,而且不是很精确。 我知道 python 浮点数有点奇怪,但我无法向自己解释为什么会发生这种情况。

这是移动代码(请注意,这不是整个脚本,而是发生错误的地方)。 另外,limit(__value, __min, __max) 是我自己创建的一个函数,你可以告诉它限制两个值之间的值

            self.state = "stand"

            # move animation
            if math.fabs(self.vel.x) > 0.1:
                temp = math.fabs(self.vel.x) / 30
                if temp < 0.4:
                    temp = 0.4
                self.state = "walk" + str(int(math.fmod(int(self.walk_time * temp), 2)))
                self.walk_time += dt
            else:
                self.walk_time = 0

            # gravity
            if not self.is_grounded:
                self.vel.y += (self.grav * (1 + float(input["down"]))) * dt
            self.vel.y = limit(self.vel.y, -21, 21)

            # set acc to input
            self.acc.x = (float(input["right"]) - float(input["left"])) * float(not input["down"])
            if input["right"] and not input["left"]:
                self.dir = 1
            if input["left"] and not input["right"]:
                self.dir = -1

            # apply acc
            self.vel.x += (self.acc.x / 2)
            self.vel.x = limit(self.vel.x, -self.speed, self.speed)

            # handle in_air
            if self.is_grounded:
                self.in_air = 0
            else:
                self.in_air += 1 * dt

            # handle jumping
            if self.in_air <= 3:
                if input["down"] and self.in_air <= 3:
                    self.state = "duck"
                self.fall_time = 0
                # apply friction
                if self.acc.x == 0:
                    if self.vel.x > 0:
                        self.vel.x -= self.fric * dt
                        if self.vel.x <= self.fric:
                            self.vel.x = 0
                    if self.vel.x < 0:
                        self.vel.x += self.fric * dt
                        if self.vel.x >= -self.fric:
                            self.vel.x = 0
            else:
                if self.vel.y < 0:
                    self.state = "jump"
                elif self.vel.y > 1:
                    self.state = "fall" + str(int(math.fmod(int(self.fall_time / 30), 2)))
                self.fall_time += 1 * dt

            if self.is_grounded:
                self.can_jump = True
            else:
                if input["up_up"]:
                    self.can_jump = False

            # jumping
            if self.jumping == 0 and input["up"]:
                if self.in_air <= 3:
                    self.jumping += 1 * dt
            elif (0 < self.jumping <= 8) and input["up"]:
                self.jumping += 1 * dt
            else:
                self.jumping = 0
            # jump
            if input["up"] and (self.in_air <= 3 or 0 < self.jumping <= 6):
                self.vel.y = -8
                self.state = "jump"

        # collision
        self.is_grounded = False
        self.is_ceiled = False
        self.is_walled = False

        self.rect.x += self.vel.x * dt
        colls = self.collision(tiles)
        for tile in colls:
            if self.vel.x > 0:
                self.rect.right = tile.left
                self.vel.x = 0
            if self.vel.x < 0:
                self.rect.left = tile.right
                self.vel.x = 0
            # check vars
            if tile.right == self.rect.left or tile.left == self.rect.right:
                self.is_walled = True

        self.rect.y += self.vel.y * dt
        colls = self.collision(tiles)
        for tile in colls:
            if self.vel.y > 0:
                self.rect.bottom = tile.top
                self.vel.y = 0
            if self.vel.y < 0:
                self.rect.top = tile.bottom
                self.vel.y = 0

            # check vars
            if tile.top == self.rect.bottom:
                self.is_grounded = True
                self.vel.y = 0
            if tile.bottom == self.rect.top:
                self.is_ceiled = True
                self.jumping = 99

        print((self.rect.x - self.last_pos[0], self.rect.y - self.last_pos[1]))
        self.last_pos = [self.rect.x, self.rect.y]

感谢每一个帮助

【问题讨论】:

    标签: python pygame negative-number


    【解决方案1】:

    这是一个准确性问题。由于pygame.Rect 应该代表屏幕上的一个区域,所以pygame.Rect 对象只能存储整数数据。

    Rect 对象的坐标都是整数。 [...]

    将速度添加到 Rect 对象时,坐标的小数部分会丢失:

    self.rect.x += self.vel.x * dt
    
    self.rect.y += self.vel.y * dt
    

    因此,对象向左和向上移动比向右和向下移动“更快”。

    为对象的位置添加具有浮点精度的属性

    self.x = ...
    slef.y = ...
    

    将速度添加到此属性。 round 的位置并将其分配给pygame.Rect 对象:

    self.x += self.vel.x * dt
    self.rect.x = round(self.x)
    
    self.y += self.vel.y * dt
    self.rect.y = round(self.y)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-09-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多