Python code here.

# Inspired by Mats Lund:
# https://github.com/CoderMats/breakout 
# Completely rewritten

WIDTH =  640    # canvas width
HEIGHT = 400    # canvas height
P_WIDTH =  50   # paddle halfwidth
P_HEIGHT = 8    # paddle halfheight
B_ROWS = 5      # bricks, number of rows
B_COLS = 10     # bricks, number of columns
B_MARGINS = 15  # margins for bricks (bottom, side)
BALL_DIAM = 10  # diameter of ball
FPS = 30        # frames per second

# block width, height, total space
b_width = (WIDTH - 2 * B_MARGINS) // B_COLS
b_height = 40  
b_gap = 15      # gap between blocks

# constants, helper variables
bw2 = b_width // 2 
bh2 = b_height // 2
dw = (b_width - b_gap) // 2
dh = (b_height - b_gap) // 2
r = BALL_DIAM // 2    # ball diameter
y_paddle = HEIGHT - 30

cell_colors = {1:"green" , 2:"blue" , 3:"red" , 4:"yellow"}

game = None

def setup():
    global game
    createCanvas(WIDTH, HEIGHT, P2D)
    rectMode(CENTER)
    frameRate(FPS)
    noCursor()
    game = Game()

def new_game():
    global game
    new_level = game.level + int(game.blocks_gone)
    game = Game(level=new_level)
        
def draw():
    global game
    if game.blocks_gone:
        new_game()    
    if not game.game_over:
        game.paddle.x = min(WIDTH - P_WIDTH, max(mouseX, P_WIDTH))
    game.update()        

def keyPressed():
    if key == " ":
        new_game()

class Ball(object):
    def __init__(self,level=1):
        # ball velocity
        self.vel = PVector(3 + int(1.5 * level),-3 - int(1.5 * level))
        xp = WIDTH // 2 + int(random(-P_WIDTH - 40,P_WIDTH + 40))
        yp = y_paddle - P_HEIGHT // 2 - r - 1      
        self.pos = PVector(xp,yp)                   # ball position

    def update(self):    
        self.pos = PVector.add(self.pos,self.vel)
        if (self.pos.x >= WIDTH or self.pos.x <= 0):  
            self.vel.x = -self.vel.x
        if (self.pos.y <= 0):
            self.vel.y = -self.vel.y

class Game(object):
    def __init__(self,level=1):
        self.paddle = PVector(WIDTH // 2, HEIGHT - 30)
        self.level = level
        self.ball = Ball()
        self.score = 0 
        self.blocks = [int(random(1.5,4.5)) for k in  range(B_ROWS * B_COLS)]
        self.game_over = False
        self.blocks_gone = False
        # x, y positions of block centers
        self.centers = [((i % B_COLS) * b_width + B_MARGINS + bw2,
                         b_height * (i // B_COLS) + B_MARGINS + bh2) 
                         for i in range(B_ROWS * B_COLS)]

    def update_ball(self):
        self.ball.update()
        px, py = self.paddle.x, self.paddle.y
        if ((px - P_WIDTH -r) <= self.ball.pos.x
             <= (px + P_WIDTH + r) and 
            (py - P_HEIGHT - r <= self.ball.pos.y 
             <= py - P_HEIGHT)):
            # ball is hitting paddle rectangle, reverse y_speed
            self.ball.vel.y = -self.ball.vel.y
            self.score = self.score + 1
        fill(100,100,200)
        ellipse(self.ball.pos.x, self.ball.pos.y, BALL_DIAM, BALL_DIAM)

            
    def update_paddle(self):
        fill(0,255,0)
        rect(self.paddle.x, self.paddle.y, 2 * P_WIDTH, 2* P_HEIGHT)
        if (self.ball.pos.y >= HEIGHT):
            fill(255) 
            textSize(40)
            textAlign(CENTER)
            text("Game over", WIDTH // 2, HEIGHT // 2 + 40)
            self.game_over = True 
    
    def update_texts(self):            
        background(25)
        noStroke()
        # Set fill color to white
        fill(255)
        # Display score
        textSize(16)
        textAlign(RIGHT)
        text("Score", 80, HEIGHT - 6)
        textAlign(LEFT)
        text(self.score, 90, HEIGHT - 6)
        # text("Frames: %.1f" %frameRate(), 130, HEIGHT - 6) 
        # Display level
        textAlign(RIGHT)
        text("Level", WIDTH - 50, HEIGHT - 6)
        textAlign(LEFT)
        text(self.level, WIDTH - 40, HEIGHT - 6)

    def update_blocks(self):
        self.blocks_gone = True
        # Loop through all the potential blocks
        collide = False

        for i in range(B_ROWS * B_COLS):
            # Check if we have that block
            if (self.blocks[i]):
                x_cent, y_cent = self.centers[i]
                self.blocks_gone = False
                    
                if not collide:
                    bx, by = self.ball.pos.x, self.ball.pos.y     
                    # check bounce on top/bottom
                    if ((x_cent - dw - r < bx < x_cent + dw + r) and 
                        ((y_cent + dh < by < y_cent + dh + r) or 
                        (y_cent -dh - r < by < y_cent - dh))):
                        self.blocks[i] = 0
                        self.ball.vel.y = -self.ball.vel.y
                        self.score = self.score + 5
                        collide = True
                     
                    # check bounce on left/right
                    if ((y_cent - dh - r < by < y_cent + dh + r) and 
                        ((x_cent + dw < bx < x_cent + dw + r) or 
                        (x_cent - dw -r < bx < x_cent - dw))):
                        self.blocks[i] = 0
                        self.ball.vel.x = -self.ball.vel.x
                        self.score = self.score + 5
                        collide = True
            if collide:
                break
                    
    def draw_blocks(self):
        for i in range(B_ROWS * B_COLS):
            if (self.blocks[i]):
                fill(cell_colors[self.blocks[i]])
                x_cent, y_cent = self.centers[i]
                rect(x_cent, y_cent, 2 * dw, 2 * dh)
                        
    def update(self):
        self.update_texts()
        self.update_ball()
        self.update_paddle()
        self.update_blocks()    
        self.draw_blocks()