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

Canvas을 사용하여 벽돌깨기 게임 만들기9 (마우스로 패들 조종하기)

by 억만장작 2021. 7. 18.

마우스로 paddle을 컨트롤 해보자

 

먼저 마우스의 움직임을 감지하기 위해 addEventListener()를 사용하자.

document.addEventListener("mousemove", mouseMoveHandler, false)

 

위에서 사용한 mouseMoveHandler()를 정의해주자.

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

event.clinetX에는 전체 뷰포트를 기준으로 x값을 반환한다. 따라서 canvas의 좌측끝이 0인 것에 기준을 둬야한다. 그래서 relativeX를 구했고 paddle의 정 중앙에 마우스가 위치할 수 있도록 paddleX = relativeX - paddleWidth / 2를 넣어주었다.

 

최종코드

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
// 벽돌
const brickRowCount = 3
const brickColumnCount = 5
const brickWidth = 75
const brickHeight = 20
const brickPadding = 10
const brickOffsetTop = 30
const brickOffsetLeft = 30

let score = 0

let bricks = []
for (let c = 0; c < brickColumnCount; c++) {
	bricks[c] = []
	for(let r = 0; r < brickRowCount; r++) {
		bricks[c][r] = { x: 0, y: 0, status: 1}
	}
}

function drawScore() {
	ctx.font = "16px Arilal"
	ctx.fillStyle = "#0095DD"
	ctx.fillText("Score: " + score, 8, 20)
}

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

function collisionDetection() {
	for (let c = 0; c < brickColumnCount; c++) {
		for (let r = 0; r < brickRowCount; r++) {
			let b = bricks[c][r]
			if (b.status === 1 && x > b.x && x < b.x + brickWidth && y > b.y && y < b.y + brickHeight) {
				dy = -dy
				b.status = 0
				score++
				if (score === brickRowCount * brickColumnCount) {
					clearInterval(tmp)
					alert("YOU WIN, CONGRATURATIONS!")
					document.location.reload()
				}
			}
		}
	}
}

function drawBricks() {
	for (let c = 0; c < brickColumnCount; c++) {
		for(let r = 0; r < brickRowCount; r++) {
			if (bricks[c][r].status === 0)
				continue
			let brickX = (c * (brickWidth + brickPadding)) + brickOffsetLeft
			let brickY = (r * (brickHeight + brickPadding)) + brickOffsetTop
			bricks[c][r].x = brickX
			bricks[c][r].y = brickY
			ctx.beginPath()
			ctx.rect(brickX, brickY, brickWidth, brickHeight)
			ctx.fillStyle = "#0095DD"
			ctx.fill()
			ctx.closePath()
		}
	}
}

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 = "white"
	ctx.fill()
	ctx.strokeStyle = "gray"
	ctx.stroke()
	ctx.closePath()
}

function draw() {
	ctx.clearRect(0, 0, canvas.width, canvas.height)
	drawBricks()
	drawBall()
	drawPaddle()
	drawScore()
	collisionDetection()
	// 공 체크
	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 + 0.15 * score)
	y += dy * (ballSpeed + 0.15 * score)
}
document.addEventListener("keydown", keyDownHandler, false)
document.addEventListener("keyup", keyUpHandler, false)
document.addEventListener("mousemove", mouseMoveHandler, false)

let tmp = setInterval(draw, 10)

 

결과물

댓글