harunpehlivan
3/6/2018 - 7:20 PM

breakout game

breakout game

@import url('https://fonts.googleapis.com/css?family=Press+Start+2P');

* {
    padding: 0;
    margin: 0;
}

body {
    margin-top: 50px;
    margin-bottom: 50px;
    background: url("http://seanmurphy.eu/breakout-game/assets/bg.jpg");
}

canvas {
    background: rgba(21,21,21, 0.7);
    display: block;
    margin: 0 auto;
    border: 7px solid #CD1FD8;
    box-shadow: 0px 0px  15px 4px  rgba(255,255,255, 0.25);
    border-radius: 11px;
}

#title {
    color: white;
    text-align: center;
    margin: 20px;
}

h1 {
    font-family: 'Press Start 2P', sans-serif;
}

#control-area {
    color: white;
    text-align: center;
    text-shadow: 5px 5px 5px #000;
    font-family: Verdana, Geneva, Tahoma, sans-serif;
    width: 1260px;
    border: 7px solid #CD1FD8;
    box-shadow: 0px 0px  15px 4px  rgba(255,255,255, 0.25);
    border-radius: 11px;
    background: rgba( 12, 7, 48, 0.5);
    margin: auto;
    margin-top: 25px;
    padding: 15px;
    cursor: pointer;
    font-family: 'Press Start 2P', sans-serif;
}

#footer {
    text-align: center;
    color: white;
    font-family: Verdana, Geneva, Tahoma, sans-serif;
    margin-top: 20px;
}

#footer a {
    color: pink;
    font-weight: bold;
}

// canvas
const canvas = document.getElementById("canvas");
const ctx = canvas.getContext("2d");
let score = 0;
let started = false;
let time = 0;
let displayTime = "0:00";
const text = document.getElementById("text");
const controlArea = document.getElementById("control-area");
text.innerHTML = "Go!";
let bricksRemaining = 0;

// sound
const paddleSound = new Audio('http://seanmurphy.eu/breakout-game/assets/paddleSound.wav');
const brickSound = new Audio('http://seanmurphy.eu/breakout-game/assets/brickSound.wav');
const music = new Audio('http://seanmurphy.eu/breakout-game/assets/music.mp3');
music.loop = true;
music.volume = 0.2;
music.play();

// ball
let x = canvas.width / 2;
let y = canvas.height - 100;
let bx = 2;
let by = -2;
const ballRadius = 20;

// paddle
const paddleWidth = 105;
const paddleHeight = 15;
let px = (canvas.width / 2) - paddleWidth;
let py = (canvas.height - 80) - paddleHeight;

// movement
let right = false;
let left = false;
let mouse = false;
document.addEventListener("keydown", keyDownHandler);
document.addEventListener("keyup", keyUpHandler);
document.addEventListener("mousemove", mouseMoveHandler);

// bricks
const brickWidth = 106;
const brickHeight = 30;
const brickRows = 6;
const brickColumns = 10;

const brickPadding = 20;
const brickPaddingX = 20;
const brickPaddingY = 20;

let colours = ["#284FB6", "#901FD8", "#D81F1F", "#D87A1F" , "#D8C91F",  "#1FD88C"]
let bricks = [];
for ( let  columns = 0; columns < brickColumns; columns++) {
        bricks[columns] = [];
    for ( let  rows = 0; rows < brickRows; rows++) {
        bricks[columns][rows] = {x: 0, y: 0, smashed: true};
    }
}

//
// Functions 
//

function reload() {
    window.location.href = window.location.href;
}

function drawBricks() {
    bricksRemaining = 0;
    for ( let columns = 0; columns < brickColumns; columns ++) {
        for (let rows = 0; rows < brickRows; rows++) {
            if (bricks[columns][rows].smashed === true) {

                const brickX = (columns * (brickWidth + brickPadding)) + brickPaddingY;
                const brickY = (rows * (brickHeight + brickPadding)) + brickPaddingX;

                bricks[columns][rows].x = brickX;
                bricks[columns][rows].y = brickY;

                ctx.beginPath();
                ctx.rect( brickX, brickY, brickWidth, brickHeight);
                ctx.fillStyle = colours[rows];
                ctx.fill();
                ctx.closePath();
                bricksRemaining += 1;
            }
        }
    }
}

// have collided with brick?
function collisionDetection() {
    for (let columns = 0; columns < brickColumns; columns++) {
        for (let rows = 0; rows < brickRows; rows++) {
            const brick = bricks[columns][rows];
            if (brick.smashed === true) {
                if ( x > brick.x && x < brick.x + brickWidth && y > brick.y && y < brick.y + brickHeight) {
                    by = -by;
                    brick.smashed = false;
                    score += 10;
                    switch (score) {
                        case 100:
                            bx = 3;
                            by = -3;
                            break;
                        case 300:
                            bx = 4;
                            by = -4;
                            break;
                        case 500:
                            bx = 5;
                            by = -5;
                            break;
                    }
                    text.innerHTML = "SMASH!!!";
                    setTimeout(setText, 500);
                    brickSound.play();


                    if (score == (brickColumns * brickRows) * 10) {
                        clearInterval(frames);
                        function flashWin() {
                            text.style.color = (text.style.color=='white') ? 'grey':'white';
                        }
                        setInterval(flashWin, 500);
                        started = false;
                        controlArea.addEventListener("click", reload);
                        text.innerHTML = `Game Over, You Won! - Score: ${score} | Time: ${displayTime}`;
                    }
                }
            }
        }
    }
}

function setText() {
    text.innerHTML = "Go!";
}

// movement events    
function keyDownHandler(event) {
    if (event.keyCode == 37) {
        left = true;
    }
    if (event.keyCode == 39) {
        right = true;
    }
}

function keyUpHandler(event) {
    if (event.keyCode == 37) {
        left = false;
    }
    if (event.keyCode == 39) {
        right = false;
    }
}

function mouseMoveHandler(event) {
    let rx = event.clientX - canvas.offsetLeft;
    if ( rx > 0 && rx < canvas.width ) {
        px = rx - paddleWidth / 2;
    }
}

function drawPaddle() {
    ctx.beginPath();
    ctx.rect( px, py, paddleWidth, paddleHeight);
    ctx.fillStyle = "#CD1FD8";
    ctx.fill();
    ctx.closePath();
}

function drawBall() {
    ctx.beginPath();
    ctx.arc( x, y, ballRadius, 0, 2 * Math.PI);
    ctx.fillStyle = "#CD1FD8";
    ctx.fill();
    ctx.closePath();
}

function drawBricksRemaining() {
    ctx.font = "20px Monospace";
    ctx.fillStyle = "#fff";
    ctx.fillText(`Remaining: ${bricksRemaining}`, (canvas.width / 2) - 60, 20);
}

function drawScore() {
    ctx.font = "20px Monospace";
    ctx.fillStyle = "#fff";
    ctx.fillText("Score: "+ score, 8, 20);
}

function countTime() {
        setInterval( function(){
            time += 1;
            let minutes = Math.floor(time / 60);
            let seconds = time - minutes * 60;
            if (seconds < 10) {
                seconds = "0" + seconds;
            }
            displayTime = `${minutes}:${seconds}`;
        }, 1000);
}
countTime();

function drawTime() {
    ctx.font = "20px Monospace";
    ctx.fillStyle = "#fff";
    ctx.fillText("Time: "+ displayTime, 1150, 20);
}

// draw event
function draw() {
    // clear for next frame
    ctx.clearRect(0, 0, canvas.width, canvas.height);
    drawBricks();
    drawBall();
    drawPaddle();
    drawScore();
    drawBricksRemaining() 
    drawTime();
    collisionDetection();

    started = true;

    // collision detection and reverse direction
    if ( x + bx > canvas.width - ballRadius || x + bx < ballRadius) {
        bx = -bx;
    }
    
    if ( y + by < ballRadius) {
        by = -by;
    }
   
    if ( y + by > py) {
        // collision with paddle
        if (x > px && x < px + paddleWidth) {
            by = -by ;
            paddleSound.play();
       }
    }

     // collision with bottom border // END GAME
    if ( y + by > canvas.height - ballRadius) {
        clearInterval(frames);
        controlArea.addEventListener("click", reload);
        started = false;
        function flashLose() {
            text.style.color = (text.style.color=='white') ? 'grey':'white';
        }
        setInterval(flashLose, 500);
        text.innerHTML = `You Lose, Try Again!  - Score: ${score} | Time: ${displayTime}`;
    }
 
    // change paddle direction
    if (right && px < canvas.width - paddleWidth) {
        px += 8;
    }
    if (left && px > 0) {
        px -= 8
    }
    x += bx;
    y += by;
}
draw();

const frames = setInterval(draw, 5);







<div id="title">
            <h1>BreakOut JavaScript/HTML5 Game</h1>
            <br />
            <p style="font-family: verdana;">** Controls: Use your mouse or arrows keys to move left and right **</p>
        </div>
        <canvas id="canvas" height="720" width="1280"></canvas>
        <div id="control-area">
            <p id="text"></p>
        </div>
        <div id="footer">
            <p>Design and Code by - <a href="https://harunpehlivantebimtebitagem.carrd.co/">HARUN PEHLİVAN</a> -</p>
        </div>