微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

pygame-如何检查是否与数组中的任何矩形发生碰撞?

如何解决pygame-如何检查是否与数组中的任何矩形发生碰撞?

我有一个 Box 对象数组,每个对象都有一个 rect 属性。我正在尝试检查我的播放器是否与数组中的任何矩形发生碰撞。它现在的工作方式,逻辑只适用于数组的最后一个元素,所以我的播放器只会与一个矩形碰撞,而他只是走过它们的所有其他矩形。我认为可能有更好的方法来检查与任何矩形的碰撞,但这是我所拥有的:

class Box:
def __init__(self,a,b,c,d):
    self.rect = pygame.Rect(a,d)

...

def detect_collisions(self,player_obj):
    for b in range(len(self.collision_Boxes)):
        if pygame.Rect.colliderect(self.collision_Boxes[b].rect,player_obj.top_rect):
            player_obj.can_move_up = False
        else:
            player_obj.can_move_up = True
        if pygame.Rect.colliderect(self.collision_Boxes[b].rect,player_obj.bottom_rect):
            player_obj.can_move_down = False
        else:
            player_obj.can_move_down = True
        if pygame.Rect.colliderect(self.collision_Boxes[b].rect,player_obj.left_rect):
            player_obj.can_move_left = False
        else:
            player_obj.can_move_left = True
        if pygame.Rect.colliderect(self.collision_Boxes[b].rect,player_obj.right_rect):
            player_obj.can_move_right = False
        else:
            player_obj.can_move_right = True

基本上,玩家在每条边上都有一个矩形,如果其中一条边与任何其他矩形发生碰撞,它会阻止玩家朝那个方向移动。数组collision_Boxes 确实包含了所有的Box 对象,而不仅仅是最后一个,我已经检查过了。

当我调用detect_collisions函数时,我是这样做的:

    keys = pygame.key.get_pressed()

if keys[pygame.K_w]:  # check for keystrokes
    player.faceDirection = "U"
    if player.y_pos > current_map.map_bounds_upper:  # check bounds
        current_map.detect_collisions(player)
        if player.can_move_up:
            player.move_up()

在这种情况下,有没有更好的方法来检查数组中的每个元素?这个循环哪里出了问题,导致它只在collision_Boxes中的最后一个元素上运行if语句?

解决方法

每次在循环中执行代码时,都会设置所有 4 个状态(can_move_upcan_move_down can_move_leftcan_move_right )。在每次循环迭代中,前一次循环的结果都会被覆盖。最后只设置上次运行的结果。

在循环之前设置状态变量,但在循环内重置它们:

def detect_collisions(self,player_obj):

    player_obj.can_move_up = True
    player_obj.can_move_down = True
    player_obj.can_move_left = True
    player_obj.can_move_right = True

    for b in self.collision_boxes:
        if player_obj.top_rect.colliderect(b.rect):
            player_obj.can_move_up = False
        if player_obj.bottom_rect.colliderect(b.rect):
            player_obj.can_move_down = False
        if player_obj.left_rect.colliderect(b.rect):
            player_obj.can_move_left = False
        if player_obj.right_rect.colliderect(b.rect):
            player_obj.can_move_right = False

您可以通过创建 pygame.Rect 对象列表并使用 pygame.Rect.collidelist 来简化代码:

collidelist(list) -> index
测试矩形是否与矩形序列中的任何一个碰撞。返回找到的第一个碰撞的索引。如果未发现冲突,则返回索引 -1。

def detect_collisions(self,player_obj):

    rect_list = [b.rect for b in self.collision_boxes]

    player_obj.can_move_up =  player_obj.top_rect.collidelist(rect_list) == -1
    player_obj.can_move_down = player_obj.bottom_rect.collidelist(rect_list) == -1
    player_obj.can_move_left = player_obj.left_rect.collidelist(rect_list) == -1
    player_obj.can_move_right = player_obj.right_rect.collidelist(rect_list) == -1

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。