0

I am trying to make my own version of brick breaker using python and pygame and I have found that my computer struggles to draw each of the bricks that make up the level every single time I run the main loop. I need to know how I can draw them and keep them drawn until I actually need to update them.

import pygame
from random import randint
pygame.init()
pygame.mouse.set_visible(True)

#Time
FPS = 60
clock = pygame.time.Clock()

#Colors
black = (0, 0, 0)
grey = (127, 127, 127)
white = (255, 255, 255)

#Display
displayInfo = pygame.display.Info()

displayWidth = displayInfo.current_w - 200
displayHeight = displayInfo.current_h - 100

borderB = 10
borderS = 1

gameDisplay = pygame.display.set_mode((displayWidth, displayHeight)) #,pygame.FULLSCREEN)
pygame.display.set_caption("Brick Breaker")
gameDisplay.fill(white)
pygame.display.update()

#Blocks
blocks = []
blockSize = 20
blockCount = 20
speed = int(blockSize / 2)


"""Classes"""

#Player
class Player():
    def __init__(self):
        #Size
        self.width = blockSize * 5
        self.height = blockSize

        #Pos
        self.x = displayWidth / 2 - self.width / 2
        self.y = displayHeight - borderB - self.height

    def move(self):
        mousePos = pygame.mouse.get_pos()
        #Check border left
        if not mousePos[0] >= borderS:
            mousePos = (borderS, mousePos[1])
        #Check border right
        elif not mousePos[0] + self.width <= displayWidth - borderS:
            mousePos = (displayWidth - borderS - self.width, mousePos[1])

        self.x = mousePos[0]

class Block():
    def __init__(self, x = 0, y = 0):
        #Size
        self.width = blockSize * 2
        self.height = blockSize

        #Position
        self.x = x
        self.y = y

    def giveDetails(self):
        print(self.x, self.y, self.width, self.height)


class Ball():
    def __init__(self):
        self.radius = int(blockSize / 2)
        self.width = blockSize

        #Co-ordinates
        self.x = int(playerBoard.x + playerBoard.width / 2)
        self.y = int(playerBoard.y - self.radius)

        self.yChange = - speed
        self.xChange = 10

    def move(self):
        if self.x - self.radius + borderS <= 0 or self.x + self.radius >=     displayWidth - borderS:
            self.xChange *= -1
        if self.y - self.radius <= 0 or self.y + self.radius >=     displayHeight - borderB:
            self.yChange *= -1  

        self.x += self.xChange
        self.y += self.yChange



"""Functions"""

def create_level():
    global blocks
    blocks = []
    xPos = blockSize
    yPos = blockSize

    #Down, across
    accross = int((displayWidth - blockSize * 2 - borderS * 2) / (blockSize     * 2 + 2))
    levelData = [1, accross]
    for row in range(levelData[0]):
        yPos += blockSize + 1
        xPos = blockSize
        for num in range(levelData[1]):
            xPos += blockSize * 2 + 1
            _ = Block(xPos, yPos)
            _.name = "block" + str(num)
            blocks.append(_)


def main_loop():
    global playerBoard, ball
    gameExit = False
    pygame.mouse.set_visible(False)

    playerBoard = Player()
    ball = Ball()
    #This creates a list called 'blocks' with all the block objects
    create_level()

    while not gameExit:
       for event in pygame.event.get():
            if event.type == pygame.QUIT:
                gameExit = True
                break
            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_ESCAPE:
                    menu()
                    gameExit = True
                    break
            if event.type == pygame.MOUSEMOTION:
                playerBoard.move()

        ball.move()

        gameDisplay.fill(white) #Clear Screen

        #Draw Player
        pygame.draw.rect(gameDisplay, grey, (playerBoard.x, playerBoard.y, 
    playerBoard.width, playerBoard.height))

        """Draw Blocks, this is where the main problem is as it runs this     loop 100 
    times or so as there are about 100 blocks. This obviously means that the 
    display.update has a hard time."""

        for item in blocks:
            pygame.draw.rect(gameDisplay, black, (item.x, item.y,     item.width, item.height))

        #Draw ball
        pygame.draw.circle(gameDisplay, black, (ball.x, ball.y), ball.radius)

        pygame.display.update()

        clock.tick(FPS)

main_loop()

pygame.quit()
quit()
Mose
  • 49
  • 7
  • What happens if you remove the line you marked with `#Clear Screen`? – Jongware Apr 16 '18 at 08:32
  • It will leave the old drawings there and draw a new one. So a moving object will just look like a line. It basically erases old drawing allowing me to re draw. – Mose Apr 16 '18 at 08:51
  • Which, as you noticed, is slow. So how about just erasing the things *that you must redraw*? – Jongware Apr 16 '18 at 08:57
  • That is what I want to learn how to do. If I were to remove "gameDisplay.fill(white)" it would still redraw everything. – Mose Apr 16 '18 at 08:59
  • @usr2564301 How would you approach this? Thanks for your help :) – Mose Apr 17 '18 at 02:51

0 Answers0