본문 바로가기
개발 공부/canvas

Canvas을 사용하여 벽돌깨기 게임 만들기5 (게임 오버)

by 억만장작 2021. 7. 18.

게임 오버 기능 적용하기

공을 튕겨내는 부분에서 공이 바닥에 도닥했을 경우에는 게임이 종료 되어야 한다.

따라서 땅에 부딪히면 경고를 띄워보자.

if (y + dy < ballRadius) {
	dy = -dy
} else if (y + dy > canvas.height - ballRadius) {
	alert("GAME OVER")
	document.location.reload()
    clearInterval(tmp)
}

여기서 문제는 경고를 띄우고 경고창을 끄면 reload가 되어야 하는데 alert()를 먼저 하고 reload()를 하면 계속해서 alert가 발생하는 것이다. 원인에 대해 생각을 했을 때 setInterval이 10ms단위로 계속 돌아가서 reload를 하기 전에 alert가 다시 호출되는 것이 가장 크다. 따라서 clearInterval을 사용하여 game이 종료되면 interval을 종료했다가 다시 실행시키는 쪽으로 코드를 짰다

 

Paddle에 공 튕기기

이제 조건을 적당히 수정하여 paddle위에 공이 부딪히면 다시 튕기고 아니고 바닥에 닿으면 GAME OVER가 뜨게 하자

if (y + dy < ballRadius) {
	dy = -dy
} else if (y + dy > canvas.height - ballRadius) {
	alert("GAME OVER")
	document.location.reload()
	clearInterval(tmp)
    // 이 곳의 조건을 바꿨다.
} else if (y + dy > canvas.height - ballRadius - paddleHeight &&
			x + dx > paddleX && x + dx < paddleX + paddleWidth) {
	dy = -dy
}

바닥에 도착하기 전이며 paddleHeight보다는 낮은 높이, 그리고 paddle의 width안에 있다면 다시 튕기게 설정했다.

 

clear할 interval에 대해서 저장하는 곳 (수정)

let tmp = setInterval(draw, 10)

 

최종 코드

const canvas = document.querySelector("#canvas")
const ctx = canvas.getContext("2d")

let ballRadius = 10
let x = canvas.width / 2
let y = canvas.height - 20
let dx = 1
let dy = -1
let ballSpeed = 1.5
// paddle
const paddleHeight = 10
const paddleWidth = 75
let paddleX = (canvas.width - paddleWidth) / 2
// event
let rightPressed = false
let leftPressed = false

function keyDownHandler(event) {
	if (event.keyCode === 39) {
		rightPressed = true
	}
	else if (event.keyCode === 37) {
		leftPressed = true
	}
}

function keyUpHandler(event) {
	if (event.keyCode === 39) {
		rightPressed = false
	}
	else if (event.keyCode === 37) {
		leftPressed = false
	}
}

function drawPaddle() {
	ctx.beginPath()
	ctx.rect(paddleX, canvas.height - paddleHeight, paddleWidth, paddleHeight)
	ctx.fillStyle = "rgba(50, 20, 20, 1)"
	ctx.fill()
	ctx.closePath()
}

function drawBall() {
	ctx.beginPath()
	ctx.arc(x, y, ballRadius, 0, Math.PI * 2, false)
	ctx.fillStyle = "blue"
	ctx.fill()
	ctx.strokeStyle = "red"
	ctx.stroke()
	ctx.closePath()
}

function draw() {
	ctx.clearRect(0, 0, canvas.width, canvas.height)
	drawBall()
	drawPaddle()
	// 공 체크
	if (y + dy < ballRadius) {
		dy = -dy
	} else if (y + dy > canvas.height - ballRadius) {
		alert("GAME OVER")
		document.location.reload()
		clearInterval(tmp)
	} else if (y + dy > canvas.height - ballRadius - paddleHeight &&
				x + dx > paddleX && x + dx < paddleX + paddleWidth) {
		dy = -dy
	}
	if (x + dx > canvas.width - ballRadius || x + dx < ballRadius) {
		dx = -dx
	}
	
	// 키 체크
	if (rightPressed && paddleX < canvas.width - paddleWidth) {
		paddleX += 7
	}
	if (leftPressed && paddleX > 0) {
		paddleX -= 7
	}
	x += dx * ballSpeed
	y += dy * ballSpeed
}
document.addEventListener("keydown", keyDownHandler, false)
document.addEventListener("keyup", keyUpHandler, false)

let tmp = setInterval(draw, 10)

 

결과물

댓글