如何解决Pygame中物体碰撞检测后停止移动的问题

80 阅读2分钟

在Pygame中,当一个物体与另一个物体发生碰撞时,如何使该物体停止移动。在目前的情况下,我正在尝试实现一个“固体”物体,当玩家角色与其接触时,该物体能够将玩家角色弹开。为了实现这一目标,我使用了以下代码:

huake_00198_.jpg

keys_pressed = pygame.key.get_pressed()
if 1 in keys_pressed:
    if keys_pressed[K_w]:
        self.player_l[1] += -2
        if self.player_r.colliderect(self.tower_r): self.player_l[1] -= -2
    if keys_pressed[K_a]:
        self.player_l[0] += -2
        if self.player_r.colliderect(self.tower_r): self.player_l[0] -= -2
    if keys_pressed[K_s]:
        self.player_l[1] += 2
        if self.player_r.colliderect(self.tower_r): self.player_l[1] -= 2
    if keys_pressed[K_d]:
        self.player_l[0] += 2
        if self.player_r.colliderect(self.tower_r): self.player_l[0] -= 2

然而,这个代码存在一个问题,就是当玩家角色与物体发生碰撞后,玩家角色会“卡住”在物体的Rect中。尽管玩家角色返回到碰撞发生之前的位置,但玩家角色Rect始终会被拉回物体中,并且碰撞将继续触发。在最初接触物体Rect之后,玩家角色将无法朝任何方向移动。

2、解决方案 要解决这个问题,您可以使用以下代码:

def move(self,dx,dy):
    screen.fill((COLOR),self.rect)                                 #covers over the sprite's rectangle with the background color, a constant in the program
    collisions = pygame.sprite.spritecollide(self, everything, False)
    for other in collisions:
        if other != self:
            (awayDx,awayDy) = self.moveRelative(other,-1)  #moves away from the object it is colliding with
            dx = dx + 9*(awayDx)                           #the number 9 here represents the object's resistance. When you push on an object, it will push with a force of nine back. If you make it too low, players can walk right through other objects. If you make it too high, players will bounce back from other objects violently upon contact. In this, if a player moves in a direction faster than a speed of nine, they will push through the other object (or simply push the other object back if they are also in motion)
            dy = dy + 9*(awayDy)
    self.rect.move_ip(dx,dy)                                       #this finally implements the movement, with the new calculations being used

这个代码创建了一个名为move的函数,该函数可以用于所有对象。它通过移动对象的Rect来实现对象的移动,同时还会检查对象是否与任何其他对象发生碰撞。如果发生碰撞,该函数会将对象移回碰撞发生之前的位置。

另外,为了提高代码的可读性和可维护性,您可以将move函数定义为一个类方法,并将其添加到玩家角色和物体类的定义中。这样,您就可以在需要时轻松调用该函数来移动对象。

以下是一个示例代码:

class Player(pygame.sprite.Sprite):
    def __init__(self, x, y):
        # ...

    def move(self, dx, dy):
        # ...

class Object(pygame.sprite.Sprite):
    def __init__(self, x, y):
        # ...

    def move(self, dx, dy):
        # ...

# ...

player = Player(100, 100)
object = Object(200, 200)

# ...

while True:
    # ...

    player.move(dx, dy)
    object.move(dx, dy)

    # ...

这样,您就可以通过调用player.move()和object.move()来移动玩家角色和物体了。