pygame level changing on collision

2019-06-10 10:26发布

问题:

I need to make a level change when my player object collides with ExitBock object.

My player object (half comments are in my language, but comments that are there where I need for help is translated):

class Player(Entity):
def __init__(self, x, y):
    Entity.__init__(self)
    self.xvel = 0
    self.yvel = 0
    self.onGround = False
    self.image = Surface = right_standing
    self.rect = self.image.get_rect()

def update(self, up, down, left, right, running, platforms):
    a = 0
    if up:
        # Pasokti tik ant zemes
        if self.onGround: self.yvel -= 7
    if down:
        pass
    if running:
        self.xvel = 12
    if left:
        self.xvel = -5
        self.image = left_standing
    if right:
        self.xvel = 5
        self.image = right_standing
        #BegimoAnim.play()


    if not self.onGround:
        # gravitacija + acceleracija
        self.yvel += 0.3
        # Max kritimo greitis
        if self.yvel > 100: self.yvel = 100
    if not(left or right):
        self.xvel = 0
    # Prieaugis X direkcijoje
    self.rect.left += self.xvel
    # daryti X axis collision
    self.collide(self.xvel, 0, platforms)
    # Prieaugis Y direkcijoje
    self.rect.top += self.yvel
    # Ar ore?
    self.onGround = False;
    # daryti Y axis collision
    self.collide(0, self.yvel, platforms)

def collide(self, xvel, yvel, platforms):
    for p in platforms:
        if pygame.sprite.collide_rect(self, p):
            if isinstance(p, ExitBlock):  # I need help here: what I should enter here?
                pass
            if xvel > 0:
                self.rect.right = p.rect.left

            if xvel < 0:
                self.rect.left = p.rect.right

            if yvel > 0:
                self.rect.bottom = p.rect.top
                self.onGround = True
                self.yvel = 0
            if yvel < 0:
                self.rect.top = p.rect.bottom

I tried doing somethings but they didn't worked. My ExitBlock class:

class ExitBlock(Platform):
def __init__(self, x, y):
    Platform.__init__(self, x, y)
    self.image.fill(Color("#0033FF"))

My game cycle:

while 1:
    timer.tick(60)

    for e in pygame.event.get():
        if e.type == QUIT: raise SystemExit("QUIT")
        if e.type == KEYDOWN and e.key == K_ESCAPE:
            raise SystemExit("ESCAPE")
        if e.type == KEYDOWN and e.key == K_UP:
            up = True
        if e.type == KEYDOWN and e.key == K_DOWN:
            down = True
        if e.type == KEYDOWN and e.key == K_LEFT:
            left = True
        if e.type == KEYDOWN and e.key == K_RIGHT:
            right = True
        if e.type == KEYDOWN and e.key == K_SPACE:
            running = True
        if e.type == KEYUP and e.key == K_UP:
            up = False
        if e.type == KEYUP and e.key == K_DOWN:
            down = False
        if e.type == KEYUP and e.key == K_RIGHT:
            right = False
        if e.type == KEYUP and e.key == K_LEFT:
            left = False

    #First try:
    '''if player.rect.colliderect(Finish.rect):
        currentLevel += 1
        platforms, entities, players, finishes = load_level(currentLevel)
        print(currentLevel)'''

    #Second try:
    '''if player.collide(ExitBlock):
        currentLevel += 1
        platforms, entities, players = load_level(currentLevel)'''


    ##background


    for y in range(32):
        for x in range(32):
            screen.blit(bg, (x * 32, y * 32))

    ##Update player, draw everything else##
    for e in entities:
        screen.blit(e.image, camera.apply(e))

    for player in players:
        screen.blit(player.image, camera.apply(player))

    for Finish in finishes:
        screen.blit(Finish.image, camera.apply(Finish))

    camera.update(player)
    pygame.display.update()
    player.update(up, down, left, right, running, platforms)

My whole code is here.

回答1:

The correct collision detection algorithm is

pygame.sprite.spritecollide(player, finishes, False)