簡體   English   中英

我在使用 PyGame 中的平台游戲時遇到碰撞問題

[英]I am having trouble with getting collisions to work with my platformer in PyGame

我正在 PyGame 中制作一個平台游戲,這將涉及玩家必須通過的障礙物。 我已經設置了如何制作游戲的基礎“地板”,但是當涉及到實際的“盒子”或障礙物時,我無法讓碰撞正常工作。 代碼分為 4 個文件,我將上傳這些文件,但大部分代碼位於主游戲循環文件和包含播放器本身的 class 的文件中。 碰撞邏輯發生在播放器 class 中,並在主循環中作為 function 運行。 我嘗試了各種方法來使碰撞起作用,但總是出現問題。 我想要它以便跳躍障礙物會導致玩家站在障礙物上並迎頭撞上障礙物不會讓角色通過。 雖然我沒有站在障礙物上的邏輯,但我確實有一些防止玩家跑過障礙的邏輯。 但即使這樣也有錯誤。 例如,當它應該“向后推”玩家並否定他的 xVel 以防止進一步移動越過障礙物時,跑到障礙物的右側會將我移到左側。 還有一些遇到障礙的錯誤,您可以通過運行程序找到這些錯誤,但是對於改善水平碰撞和開發垂直碰撞的任何幫助將不勝感激。 主游戲循環:

import pygame
import character as c
import levels
pygame.init()



WINWIDTH = 1200
WINHEIGHT = 700


win = pygame.display.set_mode((WINWIDTH,WINHEIGHT))
pygame.display.set_caption('Game')



all_sprites = pygame.sprite.Group()
terrainSprites = pygame.sprite.Group()
obstacleSprites = pygame.sprite.Group()
player = c.Player(win, WINWIDTH, WINHEIGHT)
all_sprites.add(player)
terrainSprites.add(levels.level1Terrain)
obstacleSprites.add(levels.level1Obstacles)

mainloop = True

clock = pygame.time.Clock()
while mainloop:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            mainloop = False




    all_sprites.update()
    terrainSprites.update()
    obstacleSprites.update()
    player.collision(player.rect.x, player.rect.y)
    win.fill((0,0,0))
    terrainSprites.draw(win)
    obstacleSprites.draw(win)
    pygame.draw.rect(win, (255, 0, 0), obstacleSprites.sprites()[0].rect, 2)
    pygame.draw.rect(win, (255, 0, 0), player.rect, 2)  # (player.rect.x + 4, player.rect.y + 5, 43, 50)
    all_sprites.draw(win)
    pygame.display.flip()
    clock.tick(60)
pygame.quit()

包含播放器 Class 和碰撞邏輯的角色文件:

import pygame

class Player(pygame.sprite.Sprite):
    def __init__(self, surface, WINWIDTH, WINHEIGHT):
        pygame.sprite.Sprite.__init__(self)
        self.framecounter = 1
        self.images = []
        self.idleframes = []
        self.surface = surface
        self.width = 40
        self.height = 60
        self.WINWIDTH = WINWIDTH
        self.WINHEIGHT = WINHEIGHT
        self.xVel = 5
        self.yVel = 5
        self.jumpActive = False
        self.jumpCounter = 12
        self.walking = False
        self.grounded = True
        #LOAD WALKCYCLE
        self.images.append(pygame.image.load("D:/PythonProjects/game/Assets/WalkCycleLeft - Copy/1.png"))
        self.images.append(pygame.image.load("D:/PythonProjects/game/Assets/WalkCycleLeft - Copy/2.png"))
        self.images.append(pygame.image.load("D:/PythonProjects/game/Assets/WalkCycleLeft - Copy/3.png"))
        self.images.append(pygame.image.load("D:/PythonProjects/game/Assets/WalkCycleLeft - Copy/4.png"))
        self.images.append(pygame.image.load("D:/PythonProjects/game/Assets/WalkCycleLeft - Copy/5.png"))
        self.images.append(pygame.image.load("D:/PythonProjects/game/Assets/WalkCycleLeft - Copy/6.png"))
        self.images.append(pygame.image.load("D:/PythonProjects/game/Assets/WalkCycleLeft - Copy/7.png"))
        self.images.append(pygame.image.load("D:/PythonProjects/game/Assets/WalkCycleLeft - Copy/8.png"))
        self.images.append(pygame.image.load("D:/PythonProjects/game/Assets/WalkCycleLeft - Copy/9.png"))
        self.images.append(pygame.image.load("D:/PythonProjects/game/Assets/WalkCycleLeft - Copy/10.png"))
        self.images.append(pygame.image.load("D:/PythonProjects/game/Assets/WalkCycleLeft - Copy/11.png"))
        self.images.append(pygame.image.load("D:/PythonProjects/game/Assets/WalkCycleLeft - Copy/12.png"))
        self.images.append(pygame.image.load("D:/PythonProjects/game/Assets/WalkCycleLeft - Copy/13.png"))
        self.images.append(pygame.image.load("D:/PythonProjects/game/Assets/WalkCycleLeft - Copy/14.png"))
        self.images.append(pygame.image.load("D:/PythonProjects/game/Assets/WalkCycleLeft - Copy/15.png"))
        self.images.append(pygame.image.load("D:/PythonProjects/game/Assets/WalkCycleLeft - Copy/16.png"))
        self.images.append(pygame.image.load("D:/PythonProjects/game/Assets/WalkCycleLeft - Copy/17.png"))
        self.images.append(pygame.image.load("D:/PythonProjects/game/Assets/WalkCycleLeft - Copy/18.png"))
        self.images.append(pygame.image.load("D:/PythonProjects/game/Assets/WalkCycleLeft - Copy/19.png"))
        self.images.append(pygame.image.load("D:/PythonProjects/game/Assets/WalkCycleLeft - Copy/20.png"))
        self.images.append(pygame.image.load("D:/PythonProjects/game/Assets/WalkCycleLeft - Copy/21.png"))
        self.images.append(pygame.image.load("D:/PythonProjects/game/Assets/WalkCycleLeft - Copy/22.png"))
        self.images.append(pygame.image.load("D:/PythonProjects/game/Assets/WalkCycleLeft - Copy/23.png"))
        self.images.append(pygame.image.load("D:/PythonProjects/game/Assets/WalkCycleLeft - Copy/24.png"))
        self.images.append(pygame.image.load("D:/PythonProjects/game/Assets/WalkCycleLeft - Copy/25.png"))
        self.images.append(pygame.image.load("D:/PythonProjects/game/Assets/WalkCycleLeft - Copy/26.png"))
        self.images.append(pygame.image.load("D:/PythonProjects/game/Assets/WalkCycleLeft - Copy/27.png"))
        self.images.append(pygame.image.load("D:/PythonProjects/game/Assets/WalkCycleLeft - Copy/28.png"))
        self.images.append(pygame.image.load("D:/PythonProjects/game/Assets/WalkCycleLeft - Copy/29.png"))
        self.images.append(pygame.image.load("D:/PythonProjects/game/Assets/WalkCycleLeft - Copy/30.png"))
        self.images.append(pygame.image.load("D:/PythonProjects/game/Assets/WalkCycleLeft - Copy/31.png"))
        self.images.append(pygame.image.load("D:/PythonProjects/game/Assets/WalkCycleLeft - Copy/32.png"))
        self.images.append(pygame.image.load("D:/PythonProjects/game/Assets/WalkCycleLeft - Copy/33.png"))
        self.images.append(pygame.image.load("D:/PythonProjects/game/Assets/WalkCycleLeft - Copy/34.png"))
        self.images.append(pygame.image.load("D:/PythonProjects/game/Assets/WalkCycleLeft - Copy/35.png"))
        self.images.append(pygame.image.load("D:/PythonProjects/game/Assets/WalkCycleLeft - Copy/36.png"))
        self.images.append(pygame.image.load("D:/PythonProjects/game/Assets/WalkCycleLeft - Copy/37.png"))
        self.images.append(pygame.image.load("D:/PythonProjects/game/Assets/WalkCycleLeft - Copy/38.png"))
        self.images.append(pygame.image.load("D:/PythonProjects/game/Assets/WalkCycleLeft - Copy/39.png"))
        self.images.append(pygame.image.load("D:/PythonProjects/game/Assets/WalkCycleLeft - Copy/40.png"))
        self.images.append(pygame.image.load("D:/PythonProjects/game/Assets/WalkCycleLeft - Copy/41.png"))
        self.images.append(pygame.image.load("D:/PythonProjects/game/Assets/WalkCycleLeft - Copy/42.png"))
        self.images.append(pygame.image.load("D:/PythonProjects/game/Assets/WalkCycleLeft - Copy/43.png"))
        self.images.append(pygame.image.load("D:/PythonProjects/game/Assets/WalkCycleLeft - Copy/44.png"))
        self.images.append(pygame.image.load("D:/PythonProjects/game/Assets/WalkCycleLeft - Copy/45.png"))
        self.images.append(pygame.image.load("D:/PythonProjects/game/Assets/WalkCycleLeft - Copy/46.png"))
        self.images.append(pygame.image.load("D:/PythonProjects/game/Assets/WalkCycleLeft - Copy/47.png"))
        self.images.append(pygame.image.load("D:/PythonProjects/game/Assets/WalkCycleLeft - Copy/48.png"))

        # LOAD JUMP UP - Idx. 48
        self.images.append(pygame.image.load("D:\PythonProjects\game\Assets\Pixel Adventure 1\Free\Main Characters\Virtual Guy\Jump (32x32).png"))

        # LOAD JUMP FALL - Idx. 49
        self.images.append(pygame.image.load("D:\PythonProjects\game\Assets\Pixel Adventure 1\Free\Main Characters\Virtual Guy\Fall (32x32).png"))


        #LOAD IDLE FRAMES - Idx. >49
        self.idleframes.append(pygame.image.load("D:/PythonProjects/game/Assets/Idle/1.png"))
        self.idleframes.append(pygame.image.load("D:/PythonProjects/game/Assets/Idle/1.png"))
        self.idleframes.append(pygame.image.load("D:/PythonProjects/game/Assets/Idle/1.png"))
        self.idleframes.append(pygame.image.load("D:/PythonProjects/game/Assets/Idle/1.png"))
        self.idleframes.append(pygame.image.load("D:/PythonProjects/game/Assets/Idle/2.png"))
        self.idleframes.append(pygame.image.load("D:/PythonProjects/game/Assets/Idle/2.png"))
        self.idleframes.append(pygame.image.load("D:/PythonProjects/game/Assets/Idle/2.png"))
        self.idleframes.append(pygame.image.load("D:/PythonProjects/game/Assets/Idle/2.png"))
        self.idleframes.append(pygame.image.load("D:/PythonProjects/game/Assets/Idle/3.png"))
        self.idleframes.append(pygame.image.load("D:/PythonProjects/game/Assets/Idle/3.png"))
        self.idleframes.append(pygame.image.load("D:/PythonProjects/game/Assets/Idle/3.png"))
        self.idleframes.append(pygame.image.load("D:/PythonProjects/game/Assets/Idle/3.png"))
        self.idleframes.append(pygame.image.load("D:/PythonProjects/game/Assets/Idle/4.png"))
        self.idleframes.append(pygame.image.load("D:/PythonProjects/game/Assets/Idle/4.png"))
        self.idleframes.append(pygame.image.load("D:/PythonProjects/game/Assets/Idle/4.png"))
        self.idleframes.append(pygame.image.load("D:/PythonProjects/game/Assets/Idle/4.png"))
        self.idleframes.append(pygame.image.load("D:/PythonProjects/game/Assets/Idle/5.png"))
        self.idleframes.append(pygame.image.load("D:/PythonProjects/game/Assets/Idle/5.png"))
        self.idleframes.append(pygame.image.load("D:/PythonProjects/game/Assets/Idle/5.png"))
        self.idleframes.append(pygame.image.load("D:/PythonProjects/game/Assets/Idle/5.png"))
        self.idleframes.append(pygame.image.load("D:/PythonProjects/game/Assets/Idle/6.png"))
        self.idleframes.append(pygame.image.load("D:/PythonProjects/game/Assets/Idle/6.png"))
        self.idleframes.append(pygame.image.load("D:/PythonProjects/game/Assets/Idle/6.png"))
        self.idleframes.append(pygame.image.load("D:/PythonProjects/game/Assets/Idle/6.png"))
        self.idleframes.append(pygame.image.load("D:/PythonProjects/game/Assets/Idle/7.png"))
        self.idleframes.append(pygame.image.load("D:/PythonProjects/game/Assets/Idle/7.png"))
        self.idleframes.append(pygame.image.load("D:/PythonProjects/game/Assets/Idle/7.png"))
        self.idleframes.append(pygame.image.load("D:/PythonProjects/game/Assets/Idle/7.png"))
        self.idleframes.append(pygame.image.load("D:/PythonProjects/game/Assets/Idle/8.png"))
        self.idleframes.append(pygame.image.load("D:/PythonProjects/game/Assets/Idle/8.png"))
        self.idleframes.append(pygame.image.load("D:/PythonProjects/game/Assets/Idle/8.png"))
        self.idleframes.append(pygame.image.load("D:/PythonProjects/game/Assets/Idle/8.png"))
        self.idleframes.append(pygame.image.load("D:/PythonProjects/game/Assets/Idle/9.png"))
        self.idleframes.append(pygame.image.load("D:/PythonProjects/game/Assets/Idle/9.png"))
        self.idleframes.append(pygame.image.load("D:/PythonProjects/game/Assets/Idle/9.png"))
        self.idleframes.append(pygame.image.load("D:/PythonProjects/game/Assets/Idle/9.png"))
        self.idleframes.append(pygame.image.load("D:/PythonProjects/game/Assets/Idle/10.png"))
        self.idleframes.append(pygame.image.load("D:/PythonProjects/game/Assets/Idle/10.png"))
        self.idleframes.append(pygame.image.load("D:/PythonProjects/game/Assets/Idle/10.png"))
        self.idleframes.append(pygame.image.load("D:/PythonProjects/game/Assets/Idle/10.png"))
        self.idleframes.append(pygame.image.load("D:/PythonProjects/game/Assets/Idle/11.png"))
        self.idleframes.append(pygame.image.load("D:/PythonProjects/game/Assets/Idle/11.png"))
        self.idleframes.append(pygame.image.load("D:/PythonProjects/game/Assets/Idle/11.png"))
        self.idleframes.append(pygame.image.load("D:/PythonProjects/game/Assets/Idle/11.png"))





        self.framecounter = 1
        self.idlecounter = 1
        self.image = self.images[self.framecounter]
        self.image = pygame.transform.scale(self.image, (50,50))
        self.rect =  self.image.get_rect()
        self.rect.x = 200
        self.rect.y = 640
        self.rect.width = 50
        self.rect.height = 50
        self.facing = None

    def update(self):

        self.walking = False
        keys = pygame.key.get_pressed()

        if keys[pygame.K_a]:
            self.rect.x -= self.xVel
            self.walkcycle()
            self.facing = 'left'
            self.walking = True
        elif keys[pygame.K_d]:
            self.rect.x += self.xVel
            self.walkcycle('right')
            self.facing = 'right'
            self.walking = True
        else:
            self.walking = False

        if self.jumpActive == False and self.grounded == True:
            if keys[pygame.K_SPACE]:
                self.jumpActive = True
        else:
            if self.jumpCounter >= -12:
                self.jumpUPAnim()
                neg = 1
                if self.jumpCounter < 0:
                    self.fallAnim()
                    neg = -1
                self.rect.y -= int((self.jumpCounter ** 2) * 0.25 * neg)
                self.jumpCounter -= 1
            else:
                self.jumpCounter = 12
                self.jumpActive = False
        if self.rect.x >= (self.WINWIDTH - 40):
            self.rect.x = int(self.WINWIDTH - 40)
        elif self.rect.x <= 0:
            self.rect.x = 0
        if self.rect.y >= (self.WINHEIGHT - 55):
            self.rect.y = int(self.WINHEIGHT - 55)
            self.grounded = True
        elif self.rect.y <= 0:
            self.rect.y = 0


        self.idleAnim(self.facing)
        self.gravity()
    def walkcycle(self, facing = None):
        self.image = self.images[self.framecounter]
        self.image = pygame.transform.scale(self.image, (50,50))
        if facing == 'right':
            self.image = pygame.transform.flip(self.image, True, False)

        self.framecounter += 1
        if self.framecounter == 48:
            self.framecounter = 1
    def jumpUPAnim(self):
        self.image = self.images[48]
        self.image = pygame.transform.scale(self.image, (50,50))
        if self.facing == 'left':
            self.image = pygame.transform.flip(self.image, True, False)
    def fallAnim(self):
        self.image = self.images[49]
        self.image = pygame.transform.scale(self.image, (50,50))
        if self.facing == 'left':
            self.image = pygame.transform.flip(self.image, True, False)
    def idleAnim(self, facing):
        if self.jumpActive == False and self.walking == False:
            self.image = self.idleframes[self.idlecounter]
            self.image = pygame.transform.scale(self.image, (50,50))
            if facing == 'left':
                self.image = pygame.transform.flip(self.image, True, False)
            self.idlecounter += 1
            if self.idlecounter == 44:
                self.idlecounter = 1
    def collision(self, store_x, store_y):
        from main import terrainSprites
        from main import obstacleSprites
        old_pos = self.rect.x, self.rect.y
        for i in terrainSprites:
            if pygame.sprite.spritecollide(self, terrainSprites, False):
                if self.rect.y < i.rect.top:
                    self.rect.bottom = i.rect.top
                    return True
                else:
                    return False
        for i in obstacleSprites:

            if pygame.sprite.spritecollide(self, obstacleSprites, False):
                if self.rect.bottom < i.rect.top:
                    self.yVel = 0
            else:
                self.yVel = 5
                self.rect.y = store_y
            if pygame.sprite.spritecollide(self, obstacleSprites, False):
                if self.rect.right < i.rect.left:
                    self.xVel = 0
            else:
                self.xVel = 5
                self.rect.x = store_x
    def gravity(self):
            self.rect.y += self.yVel

整個項目文件夾包含所有文件,包括包含用於生成地形的 class 的地形文件、包含用於生成障礙物的 class 的障礙物文件以及使用障礙物和地形類構建關卡的關卡文件。 該項目還包括資產: https://drive.google.com/drive/folders/13XirZjMSAB_p3TJFFDFYtRG-oIE0XjAz?usp=sharing

PyGame 使我們可以很容易地檢查一個 object 與另一個的碰撞,根據我的理解,你想知道一個東西是否與另一個碰撞,如果是這樣的話,我有一個很好的答案,下面的代碼我將使用firstRect就像你想檢查的與secondRect相撞的任何東西

if firstRect.colliderect(secondRect):
    # Do stuff

我真的希望這是您想要的,如果不是,您可以告訴我,我會盡力給出更好的答案

快樂編碼 - BSK - SK Studio

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM