做pygame.rect.colliderect()的更好方法

时间:2017-09-23 22:31:42

标签: python pygame

我在pygame中有一个平台游戏,玩家可以跳跃并向左/向右移动。要测试播放器是否与平台发生冲突,我使用pygame.rect.colliderect()函数。我遇到的问题是,当玩家在一个同时杀死他和一个平台的区块时,如果杀戮区位于平台左侧,他将会死亡。如果它位于平台的右侧,他就会活下去。 我想知道是否有更好的方法来测试碰撞,或者我是否必须自己制作这样的功能。

玩家是粉红色,平台是白色,死亡块是红色的。玩家不会在第一张照片中死亡,但会在第二张照片中死亡。

enter image description hereenter image description here

这是我目前的代码:

class Player(Entity):
(other things in the Player class that are irrelevant)
def update(self):
    self.xvel = 0
    keys = pygame.key.get_pressed()
    if keys[pygame.K_w] and self.onfloor: self.yvel = -2
    if keys[pygame.K_a]: self.xvel = -1
    if keys[pygame.K_s]: pass
    if keys[pygame.K_d]: self.xvel = 1
    if not self.onfloor and self.yvel < 10:
        self.yvel += .05
    self.move(self.xvel, 0)
    self.move(0, self.yvel)
def move(self, xvel, yvel):
    self.rect.x += xvel
    self.rect.y += yvel
    self.onfloor = False
    for thing in entities: # entities is a list of all entities, thing.rect is the pygame.rect.Rect instance for that entity
        if thing != self:
            if self.rect.colliderect(thing.rect):
                if isinstance(thing, End): self.won = True
                if isinstance(thing, Death): self.lost = True
                if yvel < 0:
                    self.rect.top = thing.rect.bottom
                    self.yvel = 0
                if xvel < 0: self.rect.left = thing.rect.right
                if yvel > 0:
                    self.rect.bottom = thing.rect.top
                    self.onfloor = True
                if xvel > 0: self.rect.right = thing.rect.left

我尝试制作自己的功能,但它没有用。这就是我所做的:

def entitycollide(self, entity):
sx1, sx2, sy1, sy2 = self.rect.left, self.rect.right, self.rect.top, self.rect.bottom
ex1, ex2, ey1, ey2 = entity.rect.left, entity.rect.right, entity.rect.top, entity.rect.bottom
if ((sx1 < ex1 < sx2) or (sx1 < ex2 < sx2)) and ((sy1 < ey1 < sy2) or (sy1 < ey2 < sy2)):
    return True
else: return False

1 个答案:

答案 0 :(得分:0)

一般的答案是你必须做两次通过。首先收集colliderect标识的所有对象(或所有rect.top值标识它们在播放器下的对象)。然后立即对所有物体做出反应。

在这里,它可能足以存储玩家所站立的最左侧的区块(当您考虑更多entities时,这可能会发生变化)。在考虑了所有候选者之后,对保存的块的类型做出反应。