为什么我的 player/tile 碰撞不起作用?

Why isn't my player/tile collision working?

我正在制作一个基于图块的游戏,图块是附加到图块列表的矩形,如下所示:

cell_rects = []
for y, row in enumerate(level):
    for x, cell in enumerate(row):
        if cell == 1:
            screen.blit(grass, (x * 50, y * 50))
        elif cell == 2:
            screen.blit(dirt, (x * 50, y * 50))
        else:
            screen.blit(air, (x * 50, y * 50))
        if cell != 0:
            cell_rects.append(pygame.Rect(x * 50, y * 50, 50, 50))

我的玩家角色也是长方形:

player = pygame.Rect([playerx,playery,50,100])

这是我试图使碰撞起作用的代码:

if keys[pygame.K_UP]:
    playery += -10
elif player != pygame.Rect.collidelistall(cell_rects):
    playery += 10

然而,终端输出:

  File "main.py", line 85, in <module>
    elif player != pygame.Rect.collidelist(cell_rects):
TypeError: descriptor 'collidelist' for 'pygame.Rect' objects doesn't apply to a 'list' object

我该如何修复它,让玩家和方块发生碰撞?

编辑:这是完整的程序,以防我遗漏任何内容。

import pygame
pygame.init()

screen = pygame.display.set_mode([800,450])
name = pygame.display.set_caption('Placeholder title')
gametimer = 0
walktimer = 0
walkframe = 1
playerx = 0
playery = 0
xvelocity = 0
running = True
while running:

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

    logo = pygame.image.load('assets/sprites/logo.png')

    #player
    keys = pygame.key.get_pressed()
    stand = pygame.image.load('assets/sprites/player/stand.png')
    walk1 = pygame.image.load('assets/sprites/player/walk1.png')
    walk2 = pygame.image.load('assets/sprites/player/walk2.png')
    walkcycle = [walk1, stand, walk2, stand]
    jump = pygame.image.load('assets/sprites/player/jump.png')
    player = pygame.Rect([playerx,playery,50,100])

    #tiles
    air = pygame.image.load('assets/sprites/tiles/air.png')
    grass = pygame.image.load('assets/sprites/tiles/grass.png')
    dirt = pygame.image.load('assets/sprites/tiles/dirt.png')

    if gametimer > 60:
        screen.fill((142,230,255))
        #level_tiling
        exec(open('assets/levels/level.py').read())
        cell_rects = []
        for y, row in enumerate(level):
            for x, cell in enumerate(row):
                if cell == 1:
                    screen.blit(grass, (x * 50, y * 50))
                elif cell == 2:
                    screen.blit(dirt, (x * 50, y * 50))
                else:
                    screen.blit(air, (x * 50, y * 50))
                if cell != 0:
                    cell_rects.append(pygame.Rect(x * 50, y * 50, 50, 50))
        #player_sprites
        if keys[pygame.K_UP]:
            screen.blit(jump, player)
        elif keys[pygame.K_RIGHT]:
            if walktimer > 1:
                walkframe += 1
                walktimer = 0
            else:
                walktimer += 1
            if walkframe >= 4:
                walkframe = 1
            screen.blit(walkcycle[walkframe], player)
        elif keys[pygame.K_LEFT]:
            if walktimer > 1:
                walkframe += 1
                walktimer = 0
            else:
                walktimer += 1
            if walkframe >= 4:
                walkframe = 1
            screen.blit(walkcycle[walkframe], player)
        else:
            screen.blit(stand, player)
        #walking
        if keys[pygame.K_RIGHT]:
            if xvelocity < 10:
                 xvelocity += 1
            playerx += xvelocity
        elif keys[pygame.K_LEFT]:
            if xvelocity > -10:
                xvelocity -= 1
            playerx += xvelocity
        else:
            xvelocity = 0
        #jumping
        if keys[pygame.K_UP]:
            playery += -10
        elif player != pygame.Rect.collidelist(cell_rects):
            playery += 10
    else:
        screen.blit(logo, (0,0))

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False

    pygame.display.flip()
    gametimer += 1

pygame.quit()

你这部分代码明显有问题: pygame.Rect.collidelist(cell_rects) 但是你没有在条件中包含那部分代码。

从用法上看,collidelistcollidelistall 似乎有两个参数:一个 Rect 和一个列表。 collidelist returns 列表中与 Rect 冲突的第一个索引,如果没有冲突,则为 -1collidelistall returns 所有发生碰撞的 Rect 的列表。所以行

elif player != pygame.Rect.collidelistall(cell_rects):

应该是

elif pygame.Rect.collidelist(player, cell_rects) == -1: