Question

I am trying to write a rip off 'Brick Breaker' game in Pygame. But I am currently stuck and do not know what to do know.

(blah blah blah, explain scenario much more clearly, blah blah blah, clear, clear scenario)

(I need more random text so I can post all this code)

Here is all of the code, (yes all of it):

import pygame, sys, time, random
from pygame.locals import *
pygame.init()
fpsclock = pygame.time.Clock()

WINDOWWIDTH = 450
WINDOWHEIGHT = 650
mainwindow = pygame.display.set_mode((WINDOWWIDTH, WINDOWHEIGHT), 0, 32)
pygame.display.set_caption('Luzion - Brick Breaker')

paddle = pygame.image.load('Brick Breaker - Paddle.png')
paddlerect = paddle.get_rect()
paddlerect.topleft = (190, 575)

ball = pygame.image.load ('ball.png')
ballrect = ball.get_rect()
ballrect.topleft = (195, 565)

cooltext = pygame.image.load('cooltext1.png')
cooltextrect = cooltext.get_rect()
cooltextrect.topleft = (0, 0)

BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
RED = (255, 0, 0)
GREEN = (0, 128, 0)
BLUE = (0, 0, 255)
LIME = (0, 255, 0)
TEXTCOLOR = WHITE

font = pygame.font.SysFont(None, 48)

def displaytext(text, font, surface, x, y):
    text = font.render(text, 1, TEXTCOLOR)
    textrect = text.get_rect()
    textrect.topleft = (x, y)
    surface.blit(text, textrect)

def waitforplayer():
    while True:
        for event in pygame.event.get():
            if event.type == QUIT:
                pygame.quit()
                sys.exit()
            if event.type == KEYDOWN:
                if event.key == K_ESCAPE:
                    pygame.quit()
                    sys.exit()
                return

moveleft = False
moveright = False
SPEED = 7

bmoveup = bmovedown = bmoveleft = bmoveright = False
BALLSPEED = 8

mainwindow.blit(cooltext, cooltextrect)
pygame.display.update()
time.sleep(1)

displaytext('Level 1', font, mainwindow, 150, 100)
pygame.display.update()
time.sleep(1)

displaytext('Press any key to begin...', font, mainwindow, 22, 200)
pygame.display.update()
waitforplayer()

while True:

    rb = pygame.image.load('redblock.png')
    rbrect = rb.get_rect()
    rbrect.topleft = (0, 0)

    rb1 = rb
    rb1rect = rb1.get_rect()
    rb1rect.topleft = (40, 0)

    level1blocks = [rb, rb1]
    level1rects = [rbrect, rb1rect]

    number = random.randint(0, 1)

    for event in pygame.event.get():
        if event.type == QUIT:
            pygame.quit()
            sys.exit()
        if event.type == KEYDOWN:
            if event.key == ord('a') or event.key == K_LEFT:
                moveleft = True
                moveright = False
            if event.key == ord('d') or event.key == K_RIGHT:
                moveleft = False
                moveright = True
            if event.key == ord('g'):
                bmoveup = True
                if number == 1:
                    bmoveleft = True
                else:
                    bmoveright = True
        if event.type == KEYUP:
            if event.key == ord('a') or event.key == K_LEFT:
                moveleft = False
            if event.key == ord('d') or event.key == K_RIGHT:
                moveright = False

    if moveleft and paddlerect.left > 0:
        paddlerect.left -= SPEED
    if moveright and paddlerect.right < WINDOWWIDTH:
        paddlerect.right += SPEED

    if bmovedown and ballrect.bottom < WINDOWHEIGHT:
        ballrect.top += BALLSPEED
    if bmoveup and ballrect.top > 0:
        ballrect.top -= BALLSPEED
    if bmoveleft and ballrect.left > 0:
        ballrect.left -= BALLSPEED
    if bmoveright and ballrect.right < WINDOWWIDTH:
        ballrect.right += BALLSPEED

    if ballrect.top <= 0:
        bmovedown = not bmovedown
        bmoveup = not bmoveup
    if ballrect.left <= 0:
        bmoveleft = not bmoveleft
        bmoveright = not bmoveright
    if ballrect.right >= WINDOWWIDTH:
        bmoveleft = not bmoveleft
        bmoveright = not bmoveright
    if ballrect.bottom >= WINDOWHEIGHT:
        bmovedown = not bmovedown
        bmoveup = not bmoveup

    mainwindow.fill(WHITE)
    mainwindow.blit(paddle, paddlerect)
    mainwindow.blit(ball, ballrect)

    for x in range(len(level1blocks)):
        mainwindow.blit(level1blocks[x], level1rects[x])

    for x in level1rects:
        if ballrect.colliderect(x):
            level1rects.remove([x])
            level1blocks.remove([x])

    if ballrect.colliderect(paddlerect):
        bmovedown = not bmovedown
        bmoveup = not bmoveup
        bmoveleft = not bmoveleft
        bmoveright = not bmoveright




    pygame.display.update()
    fpsclock.tick(35)

And here is my error:

    Traceback (most recent call last):
  File "C:/Python32/Luzion - Brick Breaker", line 144, in <module>
    level1rects.remove([x])
ValueError: list.remove(x): x not in list

Please help.

Was it helpful?

Solution

As you mention in the comments, both for loops are inside a larger while loop. That means that when the line

level1rects.remove(x)

happens, it will decrease the size of level1rects and cause level1rects[x] (when x is 1) to raise an exception.

The best way to fix this is to change your for loops to the following:

for b in level1blocks:
     mainwindow.blit(b, b.get_rect())

for x in level1blocks[:]:
    if ballrect.colliderect(x.get_rect()):
        level1blocks.remove(x)

This obliviates the need for level1rects- it caused too many problems, because you were removing items from the list of rectangles without removing the corresponding block from the list of blocks. Changing the first loop to for b in level1blocks: allows the code to work even as blocks disappear.

OTHER TIPS

Do a print or pprint on the level1blocks and level1rects lists, one of them doesn't have enough members for the range(2) iterator, which will try accessing the first (index 0) and second (index 1) members of each list.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top