popping um determinado elemento de uma lista em pygame

Stqrosta:

Eu recentemente comecei a fazer Atari Breakout em Pygame. Eu encontrei um problema que eu não sei como consertar. Sempre que eu executar o meu código, e a bola entra em contato com o bloco, o bloco que está colidindo com ele, não desaparece como deveria, mas o último bloco da lista. (Eu fiz uma lista de 21 pygame.Surfaces e iterar sobre ele e blit cada um). Obviamente, se a bola toca o último bloco da lista, o correto desaparece. Por favor você pode me ajudar?

Este é meu código:

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()
Rabbid76:

O que você realmente faz ist manipular uma lista (por pop), enquanto você iterar-lo. Eu recomendo a travers uma cópia da lista ( blocks[:]) e manipular a lista original. por exemplo:

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

De qualquer forma, eu recomendo criar uma classe 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

Acho que você gosta

Origin http://43.154.161.224:23101/article/api/json?id=365708&siteId=1
Recomendado
Clasificación