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