簡體   English   中英

如何檢測碰撞? pygame

[英]How to detect collision? pygame

我正在創建 platfrormer 游戲,當我死時有紅色方塊(他們應該殺了我)和白色方塊(平台),我應該在當前關卡開始時復活。 我做了碰撞檢測,但它只有在我移動時才有效(當我跳到紅色方塊並且我沒有按下任何東西時,它不起作用)

所以我真的很想知道如何更好地進行碰撞。

感謝代碼:

from pygame import *

WIN_WIDTH = 1923
WIN_HEIGHT = 1000

DISPLAY = (WIN_WIDTH, WIN_HEIGHT)
DEPTH = 32
FLAGS = 0
CAMERA_SLACK = 30

pygame.init()

green = (0, 255, 0)


screen = pygame.display.set_mode(DISPLAY, FLAGS, DEPTH)

font = pygame.font.SysFont('Consolas', 30)
text = font.render('Your Score: ', True, (0, 255, 0))
textRect = text.get_rect()
textRect.center = (40, 55)

level = [
"PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP",
"P                                                          P",
"P                                                          P",
"P                        PP                                P",
"P                                                          P",
"P                                 PP                       P",
"P                                                          P",
"P                                                          P",
"P             PP                                           P",
"P                                                          P",
"P                                                          P",
"P                                                          P",
"P                                                          P",
"P                     PP                                   P",
"P                                                          P",
"P                                                          P",
"P                                                          P",
"P                                                   P      P",
"P                            PP                     P      P",
"P                                                   P      P",
"P                                                   P      P",
"P                                                   P      P",
"P                    PP                             P      P",
"P                                                   P      P",
"P                                                   P      P",
"P           PP                                      P      P",
"P                                                   P      P",
"P                      PPP                          P     PP",
"P                                                   P      P",
"P                                                   P     LP",
    "PSSSSSSSSSSSSSSSSSSSSSSPPPSSSSSSSSSSSSSSSSSSSSSSSSSSPSSPPPPPPP",
"EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE",
]



def main():
    pygame.display.set_caption("Use W,A,S,D and Space to move!")
    timer = pygame.time.Clock()

    up = down = left = right = running = left_dash = right_dash = dashing = False
    bg = Surface((3200,32))
    bg.convert()
    bg.fill(Color("#000000"))
    entities = pygame.sprite.Group()
    platforms = []
    killing_entities = []
    another_level = []
    blockade = []
    player = Player(767, 900)


    x = y = 0


    global level
    for row in level:
        for col in row:
            if col == "P":
                p = Platform(x, y)
                platforms.append(p)
                entities.add(p)
            if col == "E":
                e = Block(x, y)
                platforms.append(e)
                entities.add(e)
            if col == "S":
                s = Spike(x, y)
                killing_entities.append(s)
                entities.add(s)
            if col == "L":
                l = Another_Level(x, y)
                another_level.append(l)
                entities.add(l)

            x += 32
        y += 32
        x = 0

    entities.add(player)
    running = True
    while running:
        screen.blit(text, textRect)

        timer.tick(65)

        for e in pygame.event.get():
            if e.type == KEYDOWN and e.key == K_SPACE:
                up = True
            if e.type == KEYDOWN and e.key == K_s:
                down = True
            if e.type == KEYDOWN and e.key == K_a:
                left = True
            if e.type == KEYDOWN and e.key == K_d:
                right = True
            if e.type == KEYDOWN and e.key == K_q:
                running = True
            if e.type == KEYDOWN and e.key == K_LEFT:
                left_dash = True
            if e.type == KEYDOWN and e.key == K_RIGHT:
                right_dash = True                

            if e.type == KEYUP and e.key == K_SPACE:
                up = False
            if e.type == KEYUP and e.key == K_s:
                down = False
            if e.type == KEYUP and e.key == K_d:
                right = False
            if e.type == KEYUP and e.key == K_a:
                left = False
            if e.type == KEYUP and e.key == K_d:
                right = False

            if pygame.sprite.spritecollideany(player, killing_entities):
                main()

            if pygame.sprite.spritecollideany(player, another_level):
                level = [
    "PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP",
    "P                                                          P",
    "P                                                          P",
    "P                                                          P",
    "P                                                          P",
    "P                                                          P",
    "P                                                          P",
    "P                                                          P",
    "P                                                          P",
    "P                                                          P",
    "P                                                          P",
    "P                                                          P",
    "P                                                          P",
    "P                                                          P",
    "P                                                          P",
    "P                                                          P",
    "P                                                          P",
    "P                                                          P",
    "P                                                          P",
    "PPS                                                        P",
    "PEE                                                        P",
    "PSS                                                        P",
    "P                                                          P",
    "P                                                          P",
    "PP                                                         P",
    "P                                                          P",
    "P                                                          P",
    "P                                                          P",
    "P                                                          P",
    "P         P                                                P",
        "PSSSSSSSSSSSSSSSSSSSSSSPPPSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSPPPP",
    "EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE",
]
                main()

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

        player.update(up, down, left, right, left_dash, right_dash, running, dashing, platforms)
        entities.draw(screen)
        
        pygame.display.flip()
        pygame.display.update()

class Entity(pygame.sprite.Sprite):
    def __init__(self):
        pygame.sprite.Sprite.__init__(self)

class Player(Entity):
    def __init__(self, x, y):
        Entity.__init__(self)
        self.xvel = 0
        self.yvel = 0
        self.onGround = False
        self.image = Surface((32,32))
        self.image.fill(Color("#0000FF"))
        self.image.convert()
        self.rect = Rect(x, y, 32, 32)

    def update(self, up, down, left, right, left_dash, right_dash, running, dashing, platforms):
        if up:
            if self.onGround: self.yvel -= 9
        if down:
            pass
        if running:
            self.xvel = 12

        if left_dash:
            self.rect.move_ip(-20, -2)
            left_dash = False
        
        if right_dash:
            self.rect.move_ip(20, -2)
            right_dash = False

        if left:
            self.xvel = -8
        if right:
            self.xvel = 8
        if not self.onGround:
            self.yvel += 0.25
            if self.yvel > 100: self.yvel = 100
        if not(left or right):
            self.xvel = 0        
        self.rect.left += self.xvel
        self.collide(self.xvel, 0, platforms)
        self.rect.top += self.yvel
        self.onGround = False
        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, Block):
                    pygame.event.post(pygame.event.Event(QUIT))
                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
                    self.onGround = False
    

class Platform(Entity):
    def __init__(self, x, y):
        Entity.__init__(self)
        self.image = Surface((32, 32))
        self.image.convert()
        self.image.fill(Color("#DDDDDF"))
        self.rect = Rect(x, y, 32, 32)

    def update(self):
        pass

class Block(Platform):
    def __init__(self, x, y):
        Platform.__init__(self, x, y)
        self.image.fill(Color("#000000"))

class Spike(pygame.sprite.Sprite):
    def __init__(self, x, y):
        Platform.__init__(self, x, y)
        self.image = Surface((33, 33))
        self.image.convert()
        self.image.fill(Color("#E70018"))
        self.rect = Rect(x, y, 33, 33)

class Another_Level(pygame.sprite.Sprite):
    def __init__(self, x, y):
        Platform.__init__(self, x, y)
        self.image = Surface((33, 33))
        self.image.convert()
        self.image.fill(Color("#8C563E"))
        self.rect = Rect(x, y, 33, 33)
        
        
if __name__ == "__main__":
    main()```

您檢查每幀中每個事件與killing_entities列表的沖突。 因此,如果事件隊列中當前沒有事件,則以下行:

if pygame.sprite.spritecollideany(player, killing_entities):
    main()

永遠不會被執行。 我猜您只希望在主循環中使用該代碼,而不是在事件處理循環中。

您的代碼中還有一些奇怪的地方,例如

  • 您不處理QUIT事件,因此您無法關閉游戲的 window。

  • 您使用相同的變量running作為主循環的條件並更改播放器的xvel

  • 也不需要更新顯示兩次(只需使用pygame.display.flip() )。

  • 你每幀將一個巨大的(3200x32px)Surface 傳送到屏幕上 1024 次。 如果你想用黑色填充屏幕,只需每幀調用screen.fill('black')

暫無
暫無

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

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