Pygame 碰撞检测失败

4

你好,我试图创建一个简单的2D平台游戏,但当我尝试检查两个对象之间的碰撞时失败了,即使这两个对象没有发生碰撞。我使用了pygame.sprite.collide_rect,但每次检查碰撞时它都返回1。我不知道为什么会这样,请帮帮我。 以下是代码: main.py

import pygame
from lib import player
level=['PPPPPPPPPPP',
       'P  P',
       'PPPPPPPPPPP',
       '',
       '',
       'PPPPPPPPPPP']


from pygame.locals import (
    K_UP,
    K_DOWN,
    K_LEFT,
    K_RIGHT,
    K_ESCAPE,
    KEYDOWN,
    QUIT,
)

white=(255,255,255)
green=(0,255,0)
blue=(0,0,255)
red=(255,0,0)
SCREEN_WIDTH = 800
SCREEN_HEIGHT = 600

pygame.init()

screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))

rb=player.Red_Block()
player1 = player.Player(screen, rb)


running = True



while running:
    platform=[]
    screen.fill((0, 0, 0))
    row_c=0
    for row in level:
        counter=0
        for item in row:
            if item == 'P':
                rb=player.Red_Block()
                platform.append(rb)
                screen.blit(rb.surf, (counter*31, row_c*31))
            counter+=1
        row_c+=1
    player1.set_platform(platform)

    for event in pygame.event.get():
        if event.type == KEYDOWN:

            if event.key == K_ESCAPE:
                running = False
            if event.key == K_DOWN:
                player1.move_down()
            if event.key == K_LEFT:
                player1.move_left()
            if event.key == K_RIGHT:
                player1.move_right()
            if event.key == K_UP:
                player1.move_up()

        elif event.type == QUIT:
            running = False
    #player1.draw()

    #screen.fill((0, 0, 0))

    player1.gravity()
    screen.blit(player1.surf, (player1.x, player1.y))



    pygame.display.flip()

lib.player.py

import pygame
from lib.block import *
white=(255,255,255)
green=(0,255,0)
blue=(0,0,255)
red=(255,0,0)


class Player(pygame.sprite.Sprite):
    def __init__(self, screen, block):
        super(Player, self).__init__()
        self.platform=None
        self.screen=screen
        self.block=block
        self.surf = pygame.Surface((20, 30))
        self.surf.fill(blue)
        self.x=120
        self.y=120
        self.rect = self.surf.get_rect()
    def move_up(self):
        self.y-=5
    def move_down(self):
        self.y += 5
    def move_left(self):
        self.x -= 5
    def move_right(self):
        self.x += 5
    def check_col(self, s1, s2):
        col = pygame.sprite.collide_rect(s1, s2)
        return col
    def set_platform(self, platform):
        self.platform = platform
    def gravity(self):
        for item in self.platform:
            if pygame.sprite.collide_rect(item, self) == 1:
                print(pygame.sprite.collide_rect(item, self))
            if pygame.sprite.collide_rect(item, self) == 0:
                print(pygame.sprite.collide_rect(item, self))
                self.y -= 1


lib.block.py

import pygame
white=(255,255,255)
green=(0,255,0)
blue=(0,0,255)
red=(255,0,0)

class Red_Block(pygame.sprite.Sprite):
    def __init__(self):
        super(Red_Block, self).__init__()
        self.surf = pygame.Surface((32, 32))
        self.surf.fill(red)
        self.rect = self.surf.get_rect()

抱歉我的英语不好

1个回答

3

一个 pygame.Surface 没有位置,只有大小。get_rect() 返回一个矩形,始终从 (0, 0) 开始。您需要设置矩形的位置。

您需要验证玩家是否与 任何 方块发生碰撞:

items = [item for item in self.platform if pygame.sprite.collide_rect(item, self)]
if not any(items):
    # [...]

跳过属性 .x.y,使用 .rect.x.rect.y 代替。
class Player(pygame.sprite.Sprite):
    def __init__(self, screen, block):
        super(Player, self).__init__()
        self.platform=None
        self.screen=screen
        self.block=block
        self.surf = pygame.Surface((20, 30))
        self.surf.fill(blue)
        self.rect = self.surf.get_rect(topleft = (120, 120))
    def move_up(self):
        self.rect.y-=5
    def move_down(self):
        self.rect.y += 5
    def move_left(self):
        self.rect.x -= 5
    def move_right(self):
        self.rect.x += 5
    def check_col(self, s1, s2):
        col = pygame.sprite.collide_rect(s1, s2)
        return col
    def set_platform(self, platform):
        self.platform = platform
    def gravity(self):
        items = [item for item in self.platform if pygame.sprite.collide_rect(item, self)]
        if not any(items):
            self.rect.y += 1

注意,Red_Block.rect属性也没有位置:
rb=player.Red_Block()
rb.rect.topleft = (counter*31, row_c*31)

此外,只需创建块列表(platform)一次即可:
platform=[]
for row_c, row in enumerate(level):
    for counter, item in enumerate(row):
        if item == 'P':
            rb=Red_Block()
            rb.rect.topleft = (counter*31, row_c*31)
            platform.append(rb)
player1.set_platform(platform)

running = True
while running:

    for event in pygame.event.get():
        if event.type == KEYDOWN:
            if event.key == K_ESCAPE:
                running = False
            if event.key == K_DOWN:
                player1.move_down()
            if event.key == K_LEFT:
                player1.move_left()
            if event.key == K_RIGHT:
                player1.move_right()
            if event.key == K_UP:
                player1.move_up()
        elif event.type == QUIT:
            running = False

    screen.fill((0, 0, 0))

    for rb in platform:
       screen.blit(rb.surf, rb.rect.topleft) 
    player1.gravity()
    screen.blit(player1.surf, player1.rect.topleft)

    pygame.display.flip()

好的,我完全不懂pygame,那么我该如何设置.rect的位置? - ToggleMountain
现在发生了更奇怪的事情。首先出现的是黑色窗口,然后大约5秒钟后矩形出现,玩家在地图下方,我该如何修复它?顺便说一句,感谢您扩展评论:D - ToggleMountain
哦,抱歉我没有粘贴代码的其余部分。但它仍然不起作用 :(。 - ToggleMountain

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接