JS 3일 11/04

권준석·2022년 11월 4일
0

벽돌깨기 게임

<!DOCTYPE html>
<html lang="kr">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<style>
    body {
        text-align: center;
    }

    #canvas {
        border: 2px solid;
    }
</style>

<body>
    <div>
        <canvas id="canvas" width="500" height="700"></canvas>
    </div>

    <div>
        <input type="button" value="게임시작" onclick="start(this.value);this.onclick='';" name="GameStart" id="start"
            this.onclick=";">
        <input type="button" value="블록삭제" onclick="start(this.value)" name="GameStart">
    </div>

</body>

<script>
    window.onload = function () {
        //캔버스 스크립트에서 사용하기위해 가져오기
        var canvas = document.getElementById("canvas");
        var ctx = canvas.getContext("2d"); //2d로 표현

        var score = 0;

        // 공 그리기 자원
        var WIDTH = canvas.width,
            HEIGHT = canvas.height;
        var x = WIDTH / 2,
            y = HEIGHT - 70;
        var dx = 2,
            dy = -2;
        var ballRadius = 10;

        var speed = 3; // 공의 속도

        // 움직임을 담을 변수
        var anim;

        // 막대 그리기 자원
        var paddleX, paddleW, paddleH

        // 막대의 움직임을 담을 자원
        var leftPaddle = false,
            rightPaddle = false;

        // 벽돌 그리기의 자원
        var bricks; //벽돌 
        var count; // 벽돌 갯수

        var Nrows; //가로 벽돌 갯수
        var Ncols; // 세로 벽돌 갯수
        var brickWidth; // 벽돌의 가로 길이
        var brickHeight; // 벽돌의 세로 높이
        var padding; // 벽돌의 간격


        //막대의 정보을 입력하는 메서드
        function init_paddle() {
            paddleX = (WIDTH / 2);
            paddleH = 10;
            paddleW = 100;
        }

        // 공의 움직임
        function init() {
            anim = window.requestAnimationFrame(draw);
        }


        //캔버스에 그려주기
        function draw() {
            // 지나간 공을 지운다
            clear();
            // 공을 그리기
            drawBall(x, y, ballRadius);

            // 막대 그리기
            rect(paddleX, (HEIGHT - paddleH) - 50, paddleW, paddleH);

            // 공의 움직임 위치
            x += (dx * speed);
            y += (dy * speed);

            //벽에 닿으면 반전
            if (x >= WIDTH - ballRadius || x <= 0 + ballRadius) {
                dx = -dx;
            }
            if (y <= 0 + ballRadius) {
                dy = -dy;
            } else if (y >= (HEIGHT - ballRadius) - 50) {
                //막대에 닿으면 y반전
                if (x > paddleX && x < paddleX + paddleW + 1) {
                    dx = -((paddleX + (paddleW / 2) - x) / (paddleW)) * 10;
                    dy = -dy;
                } else {
                    //바닥에 닿으면 게임종료
                    alert("GAME OVER!!")
                    alert("점수 : " + score);
                    document.location.reload(); // 화면
                    clearinterval(interval);// 재시작
                }
            }
            //막대의 움직임
            if (leftPaddle && paddleX > 0) {
                paddleX -= 7;
            }
            if (rightPaddle && paddleX + paddleW < WIDTH) {
                paddleX += 7;
            }

            //벽돌 그리기
            for (let i = 0; i < Nrows; i++) {
                for (let j = 0; j < Ncols; j++) {
                    if (bricks[i][j] == 1) { // 벽돌의 생명이 있을때
                        rect(j * brickWidth, i * brickHeight, // 벽돌의 갯수
                            brickWidth - padding, brickHeight - padding); // 벽돌간 간격
                    }
                }
            }

            //벽돌이 공에 맞았을때
            var row = Math.floor(y / (brickHeight + padding));
            var col = Math.floor(x / (brickWidth + padding));
            if (row < Nrows) {
                if (bricks[row][col] == 1) {
                    dy = -dy; // 벽돌에 맞았을때 반전
                    bricks[row][col] = 0; // 벽돌의 생명이 없어지고 벽돌이 사라진다
                    score += 100;
                    count--;
                }
            }
            if (count == 0) {
                alert("승리")
                alert("점수 : " + score);
                document.location.reload(); // 화면
                clearinterval(interval);// 재시작
            }

            //실직적인 움직임
            anim = window.requestAnimationFrame(draw);
        }

        //공을 지워주는 메서드
        function clear() {
            ctx.clearRect(0, 0, canvas.width, canvas.height);
        }

        //공을 그려주는 메서드
        function drawBall(x, y, r) {
            ctx.fillStyle = "#00005d";
            ctx.beginPath();
            ctx.arc(x, y, r, 0, 2 * Math.PI);
            ctx.fill();
            ctx.closePath();
        }


        // 사각형을 그리는 메서드(벽돌과 막대를 만들때 활용)
        function rect(x, y, w, h) {
            ctx.beginPath();
            ctx.rect(x, y, w, h);
            ctx.fill();
            ctx.closePath();
        }

        //벽돌의 정보를 입력하는 메서드
        function init_bricks() {
            Nrows = 5; // 벽돌의 줄 갯수
            Ncols = 6; // 벽돌의 한줄 갯수
            padding = 1; // 벽돌의 간격
            brickWidth = (WIDTH / Ncols); //벽돌의 길이
            brickHeight = 10; // 벽돌의 높이
            count = Nrows * Ncols;

            bricks = new Array(Nrows); // 벽돌 배열로 선언
            for (let i = 0; i < Nrows; i++) {
                bricks[i] = new Array(Ncols); // 벽돌의 2차원 배열 선언
                for (let j = 0; j < Ncols; j++) {
                    bricks[i][j] = 1; // 벽돌의 생명
                }
            }
        }
        //키보드가 눌릴때
        window.addEventListener('keydown', e => {
            if (e.which == 37) { // 키보드 고유넘버 오른쪽 (37)
                leftPaddle = true;
            } else if (e.which == 39) { // 키보드 고유넘버 왼쪽 (39)
                rightPaddle = true;
            }
        });

        //키보드가 때질때
        window.addEventListener('keyup', e => {
            if (e.which == 37) { // 키보드 고유넘버 오른쪽
                leftPaddle = false;
            } else if (e.which == 39) { // 키보드 고유넘버 왼쪽
                rightPaddle = false;
            }
        });

        //실행
        start = s => {
            if (s == '게임시작') {
                init();
            } else if (s == '블록삭제') {
                for (let i = 0; i < Nrows; i++) {
                    for (let j = 0; j < Ncols; j++) {
                        bricks[i][j] = 0;
                        count = 0;
                    }
                }
            }

        }
        //막대의 정보의 초기화
        init_paddle();
        //벽돌의 정보 초기화
        init_bricks();
    };


</script>


</html>
profile
ㅇㅇ

0개의 댓글