JustPaste.it
<!DOCTYPE html>
<html lang="en">
<head>
    <meta content="text/html;charset=utf-8" http-equiv="Content-Type">
    <meta content="utf-8" http-equiv="encoding">
</head>

<body style="background-color: rgb(50, 50, 50);">
<canvas id="gameCanvas" width="800" height="600"></canvas>

<script>
var ballX = 75;
var ballY = 75;
const BALL_SPEED_X_INIT = 1;
const BALL_SPEED_Y_INIT = 3.5;
var ballSpeedX = BALL_SPEED_X_INIT;
var ballSpeedY = BALL_SPEED_Y_INIT;
var ballFired = false;
const BALL_RADIUS = 8;

const LIFES_CONST = 3;
var lifes = LIFES_CONST;

const BRICK_W = 80;
const BRICK_H = 20;
const BRICK_GAP = 2;
const BRICK_COLS = 10;
const BRICK_ROWS = 14;
var brickGrid = new Array(BRICK_COLS * BRICK_ROWS);
var bricksLeft = 0;

const PADDLE_WIDTH = 100;
const PADDLE_THICKNESS = 10;
const PADDLE_DIST_FROM_EDGE = 60;
var paddleX = 400;
var paddleSpeed = 10;

var canvas, canvasContext;

const UPDATES_PER_SECOND = 120;
const FRAMES_PER_SECOND = 60;

var mouseX = 0;
var mouseY = 0;

var mouseDown = false;

var arrowLeftDown = false;
var arrowRightDown = false;
var acceleration = 1;

var gameOver = false;
var gameWon = false;

//******** TEST SOUND BEGIN *******/


//******** TEST SOUND END *******/

const CHEAT_MOVE_BALL_WITH_MOUSE = true;
const CHEAT_BALL_BOUNCES_OFF_BOTTOM = true;

/************************************************************ ONLOAD ************************************************************/

window.onload = function() {
    canvas = document.getElementById('gameCanvas');
    canvasContext = canvas.getContext('2d');

    setInterval(updateAll, 1000/UPDATES_PER_SECOND);

    canvas.addEventListener('mousemove', updateMousePos);
    //window.addEventListener('onkeydown', this.onKeyDownListener, false);
    document.onmousedown = onMouseDownListener;
    //document.onmouseup = onMouseUpListener;
    document.onkeydown = onKeyDownListener;
    document.onkeyup = onKeyUpListener;

    brickReset();
    ballReset();
    lifes = LIFES_CONST; //ballreset() subtracts a life, therefore set lifes to default again
}

/************************************************************ EVENT LISTENERS ************************************************************/

function updateMousePos(evt) {
    var rect = canvas.getBoundingClientRect();
    var root = document.documentElement;

    mouseX = evt.clientX - rect.left - root.scrollLeft;
    mouseY = evt.clientY - rect.top - root.scrollTop;

    paddleX = mouseX - PADDLE_WIDTH/2;

    if(CHEAT_MOVE_BALL_WITH_MOUSE && mouseDown) { //cheat / hack to test ball in any position
        ballX = mouseX;
        ballY = mouseY;
        ballSpeedX = 1;
        //ballSpeedY = -4;
    }
}

function onKeyDownListener(evt) {
    var keyCode = evt.which || evt.keyCode;
    switch(keyCode) {
        case 37:
            arrowLeftDown = true;
            break;
        case 39:
            arrowRightDown = true;
            break;
        case 32: //spacebar
        case 38: //arrow up
            if(gameOver || gameWon) {
                gameOver = false;
                gameWon = false;
                brickReset();
            } else if(ballFired == false){
                fireNewBall();
            }
    }
}

function onKeyUpListener(evt) {
    var keyCode = evt.which || evt.keyCode;
    if(keyCode == 37) {
        arrowLeftDown = false;
    }
    if(keyCode == 39) {
        arrowRightDown = false;
    }
    acceleration = 1;
}

function onMouseDownListener() {
    mouseDown = true;
    if(gameOver || gameWon) {
        gameOver = false;
        gameWon = false;
        brickReset();
    } else if(ballFired == false) {
        fireNewBall();
    }
}

function onMouseUpListener() {
    mouseDown = true;
}

/************************************************************ GAME FUNCTION ************************************************************/

function updateAll() {
    moveAll();
    drawAll();
}

/************************************************************ MOVE STUFF ************************************************************/

function moveAll() {
    paddleMove();
    
    ballMove();
    
    ballBrickHandling();
    
    ballPaddleHandling();
}

function paddleMove() {
    if(arrowRightDown && paddleX + PADDLE_WIDTH/2 <= canvas.width) {
        paddleX += paddleSpeed * acceleration;
    }
    if(arrowLeftDown && paddleX + PADDLE_WIDTH/2 >= 0) {
        paddleX -= paddleSpeed * acceleration;
    }
    if(acceleration <= 2) {
        acceleration += 0.2;
    }
}

function ballMove() {
    if(ballFired && !gameOver && !gameWon) {
        ballX += ballSpeedX;
        ballY += ballSpeedY;

        if(ballX < 0 && ballSpeedX < 0.0) { //left
            ballSpeedX *= -1;
        }
        if(ballX > canvas.width && ballSpeedX > 0.0) { // right
            ballSpeedX *= -1;
        }
        if(ballY < 0 && ballSpeedY < 0.0) { // top
            ballSpeedY *= -1;
        }
        if(ballY > canvas.height) { // bottom
            if(CHEAT_BALL_BOUNCES_OFF_BOTTOM) {
                ballSpeedY *= -1;
            } else {
                ballReset();
                if(lifes <= 0) {
                    gameOver = true;
                    //brickReset();
                }
            }
        }
    } else {
        ballX = paddleX + PADDLE_WIDTH/2;
        ballY = canvas.height - PADDLE_DIST_FROM_EDGE - BALL_RADIUS - 4;
    }
}

/************************************************************ COLLISION DETECTION ************************************************************/

function ballBrickHandling() {
    var ballBrickCol = Math.floor(ballX / BRICK_W);
    var ballBrickRow = Math.floor(ballY / BRICK_H);
    var brickIndexUnderBall = rowColToArrayIndex(ballBrickCol, ballBrickRow);

    if(ballBrickCol >= 0 && ballBrickCol < BRICK_COLS &&
        ballBrickRow >= 0 && ballBrickRow < BRICK_ROWS) {

        if(isBrickAtColRow( ballBrickCol,ballBrickRow )) {
            brickGrid[brickIndexUnderBall] = false;
            bricksLeft--;
            ballSpeedX += Math.sign(ballSpeedX)*(0.5/ballBrickRow);
            ballSpeedY += Math.sign(ballSpeedY)*(0.5/ballBrickRow);
            console.log(ballSpeedY);
            // console.log(bricksLeft);

            var prevBallX = ballX - ballSpeedX;
            var prevBallY = ballY - ballSpeedY;
            var prevBrickCol = Math.floor(prevBallX / BRICK_W);
            var prevBrickRow = Math.floor(prevBallY / BRICK_H);

            var bothTestsFailed = true;

            if(prevBrickCol != ballBrickCol) {
                if(isBrickAtColRow(prevBrickCol, ballBrickRow) == false) {
                    ballSpeedX *= -1;
                    bothTestsFailed = false;
                }
            }
            if(prevBrickRow != ballBrickRow) {
                if(isBrickAtColRow(ballBrickCol, prevBrickRow) == false) {
                    ballSpeedY *= -1;
                    bothTestsFailed = false;
                }
            }

            if(bothTestsFailed) { // armpit case, prevents ball from going through
                ballSpeedX *= -1;
                ballSpeedY *= -1;
            }

        } // end of brick found
    } // end of valid col and row
} // end of ballBrickHandling func

function isBrickAtColRow(col, row) {
    if(col >= 0 && col < BRICK_COLS &&
        row >= 0 && row < BRICK_ROWS) {
         var brickIndexUnderCoord = rowColToArrayIndex(col, row);
         return brickGrid[brickIndexUnderCoord];
    } else {
        return false;
    }
}

function rowColToArrayIndex(col, row) {
    return col + BRICK_COLS * row;
}

function ballPaddleHandling() {
    var paddleTopEdgeY = canvas.height-PADDLE_DIST_FROM_EDGE;
    var paddleBottomEdgeY = paddleTopEdgeY + PADDLE_THICKNESS;
    var paddleLeftEdgeX = paddleX;
    var paddleRightEdgeX = paddleLeftEdgeX + PADDLE_WIDTH;
    if( ballY > paddleTopEdgeY && // below the top of paddle
        ballY < paddleBottomEdgeY && // above bottom of paddle
        ballX > paddleLeftEdgeX && // right of the left side of paddle
        ballX < paddleRightEdgeX) { // left of the left side of paddle
        
        ballSpeedY *= -1;

        var centerOfPaddleX = paddleX+PADDLE_WIDTH/2;
        var ballDistFromPaddleCenterX = ballX - centerOfPaddleX;
        ballSpeedX = ballDistFromPaddleCenterX * 0.35;

        if(bricksLeft == 0) {
            gameWon = true;
            //brickReset();
        } // out of bricks
    } // ball center inside paddle
} // end of ballPaddleHandling

/************************************************************ RESETS / GAME SETUP STUFF ************************************************************/

function brickReset() {
    bricksLeft = 0;
    var i;
    for(i=0; i< 3*BRICK_COLS; i++) {
        brickGrid[i] = false;
    }
    for(; i<BRICK_COLS * BRICK_ROWS; i++) {
        brickGrid[i] = true;
        bricksLeft++;
    } // end of for each brick
    lifes = LIFES_CONST;

    gameWon = false;
    gameOver = false;
} // end of brickReset func

function ballReset() {
    /* no need for that because ball gets positioned on pedal
    ballX = canvas.width/2;
    ballY = canvas.height/2; */
    //ballSpeedX = 1;
    ballFired = false;
    lifes --;
}

function fireNewBall() {
    ballFired = true;
    ballSpeedX = BALL_SPEED_X_INIT;
    ballSpeedY = BALL_SPEED_Y_INIT;
}

/************************************************************ DRAWING ************************************************************/

function drawAll() {
    colorRect(0,0, canvas.width,canvas.height, 'black'); // clear screen

    drawLifes();

    colorCircle(ballX,ballY, BALL_RADIUS, 'white'); // draw ball

    colorRect(paddleX, canvas.height-PADDLE_DIST_FROM_EDGE,
                PADDLE_WIDTH, PADDLE_THICKNESS, 'white'); //draw paddle

    drawBricks();
    
    if(gameOver) {
        colorTextAdv("You Lost.", 350, 350, 'red', "center", "32px Arial");
        colorTextAdv("click to continue...", 350, 420, 'red', "center", "20px Arial");
        return;
    }
    if(gameWon) {
        colorTextAdv("You Won!", 350, 350, 'green', "center", "32px Arial");
        colorTextAdv("click to continue...", 350, 420, 'green', "center", "20px Arial");
        return;
    }
}

function drawBricks() {
    for(var eachRow=0;eachRow<BRICK_ROWS;eachRow++) {
        for(var eachCol=0;eachCol<BRICK_COLS;eachCol++) {

            var arrayIndex = rowColToArrayIndex(eachCol, eachRow);

            if(brickGrid[arrayIndex]) {
                colorRect(BRICK_W*eachCol,BRICK_H*eachRow,
                    BRICK_W-BRICK_GAP,BRICK_H-BRICK_GAP,
                    'rgb('+ Math.floor(255-(255*eachRow/BRICK_ROWS)) +','+ 0 +','+ Math.floor(255*(eachRow/BRICK_ROWS)) +')' );
            } // end of is this brick here
        } // end of for each brick
    } // end of for each row
} // end of drawBricks func

function drawLifes() {
    for(var i = 0; i < lifes; i++) {
        colorCircle(20 + 28*i, canvas.height - 20, 10, 'white');
    }
}

/************************************************************ DRAWING BASIC FUNCTIONS ************************************************************/

function colorRect(topLeftX,topLeftY, boxWidth,boxHeight, fillColor) {
    canvasContext.fillStyle = fillColor;
    canvasContext.fillRect(topLeftX,topLeftY, boxWidth,boxHeight);
}

function colorCircle(centerX,centerY, radius, fillColor) {
    canvasContext.fillStyle = fillColor;
    canvasContext.beginPath();
    canvasContext.arc(centerX,centerY, 10, 0,Math.PI*2, true);
    canvasContext.fill();
}

function colorText(showWords, textX,textY, fillColor) {
    canvasContext.fillStyle = fillColor;
    canvasContext.fillText(showWords, textX, textY);
}

function colorTextAdv(text, textX, textY, fillColor, alignment, font) {
    canvasContext.fillStyle = fillColor;
    canvasContext.font=font;
    canvasContext.textAlign = alignment;
    canvasContext.fillText(text, textX, textY);
}

</script>

</body>
</html>