简体   繁体   中英

Collision detection in pygame platformer

Right now I am making a platformer game, and am having a lot of trouble with collision detection. One of the problems is that when the character is on a box, the picture constantly shifts from jumping to standing. The other is that when the character is on a box and hits another box, they are immediately transported to the bottom boxes side. If you had any insight into this problem, that would be great. This is my current collision detection program:

def update(self):

    global playerRL, jump, playerUD, counter, inMotion, onGround, onBox, jumpSize, fallSpeed, jumpCounter, allBoxes, boxes, direction, gravity, bottomTouching, boxTouching
    keys = pygame.key.get_pressed()
    previousX = self.rect.left
    previousY = self.rect.bottom
    inMotion = False
    bottomTouching = False

    if counter > 20:
        counter = 0

    def collisionDetection():
        global jump, playerRL, playerUD, counter, inMotion, onGround, onBox, jumpSize, fallSpeed, jumpCounter, allBoxes, boxes, direction, gravity, bottomTouching, boxTouching
        collided = False
        boxCounter = 0
        for plat in boxes:
            if self.rect.colliderect(plat.rect):
                if self.rect.left < plat.rect.right and self.rect.right > plat.rect.left and self.rect.bottom > plat.rect.top and self.rect.bottom < plat.rect.bottom:
                    self.rect.bottom = plat.rect.top
                    playerUD = 0
                    jumpCounter = 0
                    gravity = 0
                    onGround = True
                    collided = True
                    boxCounter += 1
                    print 'hi'
                if self.rect.right <= plat.rect.right and self.rect.left <= plat.rect.left and self.rect.bottom > plat.rect.top and self.rect.top < plat.rect.bottom:
                    self.rect.right = plat.rect.left
                    print 'right'
                if self.rect.left >= plat.rect.left and self.rect.right >= plat.rect.right and self.rect.bottom > plat.rect.top and self.rect.top < plat.rect.bottom:
                    self.rect.left = plat.rect.right
                if self.rect.left <= plat.rect.right and self.rect.right >= plat.rect.left and self.rect.top < plat.rect.bottom and self.rect.bottom > plat.rect.top:
                    self.rect.top = plat.rect.bottom
                    jumpCounter = 0
                    playerUD = 0


        if self.rect.left < 0:
            if playerRL < 0:
                self.rect.left = 0
        if self.rect.top < 0:
            if playerUD < 0:
                self.rect.top = 0
        if self.rect.right >= 960:
            if playerRL > 0:
                self.rect.right = 960
        if self.rect.bottom > 640:
            self.rect.bottom = 640
            playerUD = 0
        if self.rect.bottom == 640:
            onGround = True
        else:
            if collided == False:
                onGround = False

    keys = pygame.key.get_pressed()

    if keys[K_d] or keys[K_RIGHT]:
        direction = 'right'
        inMotion = True
        if rightTouch == False:
            counter += 1
            playerRL += 4

    if keys[K_a] or keys[K_LEFT]:
        direction = 'left'
        inMotion = True
        if leftTouch == False:
            counter += 1
            playerRL -= 4

    if keys[K_w] or keys[K_UP]:
        if onGround == True:
            bottomTouching = False
            onGround = False
            jumpSize = 8
            playerUD -= jumpSize
            jumpCounter = 11
            gravity = 1


    if onGround == True:
        if inMotion == True and counter > 10:
            if direction == 'left':
                self.image = backwardMovingPlayer
                self.mask = pygame.mask.from_surface(self.image)
                self.rect = self.image.get_rect()
                self.rect.bottom = previousY
                self.rect.left = previousX

            else:
                self.image = forwardMovingPlayer
                self.mask = pygame.mask.from_surface(self.image)
                self.rect = self.image.get_rect()
                self.rect.bottom = previousY
                self.rect.left = previousX

        else:
            if direction == 'left':
                self.image = backwardStationaryPlayer
                self.mask = pygame.mask.from_surface(self.image)
                self.rect = self.image.get_rect()
                self.rect.bottom = previousY
                self.rect.left = previousX

            else:
                self.image = forwardStationaryPlayer
                self.mask = pygame.mask.from_surface(self.image) #masks are used for cutouts
                self.rect = self.image.get_rect()
                self.rect.bottom = previousY
                self.rect.left = previousX  

    else:
        if direction == 'left':
            self.image = backwardJumpingPlayer
            self.mask = pygame.mask.from_surface(self.image) #masks are used for cutouts
            self.rect = self.image.get_rect()
            self.rect.bottom = previousY
            self.rect.left = previousX

        else:
            self.image = forwardJumpingPlayer
            self.mask = pygame.mask.from_surface(self.image) #masks are used for cutouts
            self.rect = self.image.get_rect()
            self.rect.bottom = previousY
            self.rect.left = previousX          


    if onGround == False:
        if jumpCounter > 0:
            jumpCounter -= 1
            playerUD -= jumpSize
        else:
            playerUD += gravity
            gravity += 1

    self.rect.left += playerRL
    self.rect.bottom += playerUD

    collisionDetection()

    playerUD = 0
    playerRL = 0

Pygame has collision detection built in: firstrect.colliderect(secondrect)

It returns a boolean.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM