pygame-我如何检查是否有碰撞与任何矩形在数组中?



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

class Box:
def __init__(self, a, b, c, d):
self.rect = pygame.Rect(a, b, c, 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_collision函数时,我这样做:

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_up,can_move_down,can_move_left,can_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

最新更新