벽돌깨기 게임
<!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>