【问题标题】:popping a particular element from a list in pygame [duplicate]从pygame中的列表中弹出特定元素[重复]
【发布时间】:2020-03-29 11:30:12
【问题描述】:

我最近开始在 Pygame 中制作 Atari Breakout。我遇到了一个我不知道如何解决的问题。每当我运行我的代码,并且球与块接触时,与它发生碰撞的块并没有按原样消失,而是列表中的最后一个块。 (我列出了 21 个 pygame.Surfaces 并对其进行迭代并对每一个进行 blit)。显然,如果球接触到列表中的最后一个块,正确的块就会消失。请问您能帮帮我吗?

这是我的代码:

import pygame, random, math

pygame.init()

screen = pygame.display.set_mode((800,600))
pygame.display.set_caption('Atari Breakout')

player = pygame.image.load('player copy.png')
ball = pygame.image.load('poland.png')
blocks = [pygame.image.load('block.png') for i in range(21)]


x, y = 25,25
blockx, blocky = [], []
for i in range(21):
    if i % 7 == 0:
        y += 52
        x = 25
    blockx.append(x)
    blocky.append(y)
    x += (50 + 64)

ballx, bally = 400, 300

balldx, balldy = 4,4

score = 0
score_font = pygame.font.Font('freesansbold.ttf', 32)

def show_score():
    score_text = score_font.render('Score : {}'.format(score), True, (255,255,255))
    screen.blit(score_text, (0,0))

def isCollision(x1,y1,x2,y2):
    ballRect = ball.get_rect(topleft = (x1, y1))
    playerRect = player.get_rect(topleft = (x2, y2))
    return ballRect.colliderect(playerRect)

def isCollision2(x1,y1,x2,y2):
    ballRect = ball.get_rect(topleft = (x1,y1))
    blockRect = blocks[i].get_rect(topleft = (x2,y2))
    return ballRect.colliderect(blockRect)

def blit_blocks():
    for i in range(len(blocks)):
        screen.blit(blocks[i], (blockx[i], blocky[i]))
running = True

while running:

    if score >= 21:
        running = False
    screen.fill((0,0,0))


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

    pos = pygame.mouse.get_pos()

    for i, block in enumerate(blocks):

        if isCollision2(ballx, bally, blockx[i], blocky[i]):
            balldy *= -1
            score += 1
            blocks.pop(i)

    if isCollision(ballx, bally, pos[0], 525):
        balldy *= -1
    if bally <= 0:
        balldy *= -1
    if bally >= 570:
        running = False
    if ballx <= 0:
        balldx *= -1
    if ballx >= 770:
        balldx *= -1

    ballx += balldx
    bally += balldy

    screen.blit(player, (pos[0], 525))
    screen.blit(ball, (ballx,bally))
    blit_blocks()
    show_score()
    pygame.display.update()

【问题讨论】:

    标签: python python-3.x list pygame


    【解决方案1】:

    您实际上所做的是在迭代列表时操作列表(通过pop)。我建议遍历列表的副本 (blocks[:]) 并操作原始列表。例如:

    i = 0
    for x, y, block in zip(blockx[:], blocky[:], blocks[:]):
    
            if isCollision2(ballx, bally, x, y):
                blockx.pop(i)
                blocky.pop(i)
                blocks.pop(i)
                balldy *= -1
                score += 1
            else:
                i += 1
    

    无论如何,我建议创建一个类Block

    class Block():
        def __init__(self, image, x, y)
            self.image = image
            self.x = x
            self.y = y
    
    image = pygame.image.load('block.png')
    x, y = 25,25
    blocks = []
    for i in range(21)
        if i % 7 == 0:
            y += 52
            x = 25
        blocks.append(Block(image, x, y))
        x += (50 + 64)
    
    i = 0
    for block in block[:]:
        if isCollision2(ballx, bally, block.x, block.y):
            balldy *= -1
            score += 1
            block.pop(i)
        else:
            i += 1
    

    【讨论】:

    • 非常感谢!我添加了balldy *= -1,它起作用了!我不会修改列表(如果可能的话)。
    【解决方案2】:

    在迭代时从列表中pop 是一种不好的做法,这会导致意外行为,这里:

    for i, block in enumerate(blocks):
    
            if isCollision2(ballx, bally, blockx[i], blocky[i]):
                balldy *= -1
                score += 1
                blocks.pop(i)
    

    你可以使用:

    new_blocks = []
    for i, block in enumerate(blocks):
    
            if isCollision2(ballx, bally, blockx[i], blocky[i]):
                balldy *= -1
                score += 1
            else:
                new_blocks.append(block)
    
    blocks = new_blocks
    

    【讨论】:

    • 感谢您的信息!遗憾的是,它并没有解决问题。
    猜你喜欢
    • 2022-01-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-02-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-02
    相关资源
    最近更新 更多