해당 내용은 판교고 사이드 프로젝트 진행시에 사용할 캔버스에 대한 학습 내용을 정리하였습니다.
🎮 게임 소개
판교고는 우봉고 보드게임과 동일한 규칙을 가지고 플레이할 수 있습니다. 게임 라운드마다 점수를 획득하여 최종적으로 가장 많은 점수를 획득한 사람이 우승하며 우승자에게는 판교로 이직할 수 있는 기회를 제공한다는 컨셉의 게임입니다.
🛠 기술 체크
판교고는 우봉고 보드게임과 동일한 규칙을 가지고 있습니다. 규칙에 대한 설명은 아래와 같습니다.
- 각자 개인판을 가지고 게임을 시작합니다.
- 개인판에서 주사위를 굴려 나온 값에 해당하는 칸에 그려진 타일 모양을 가져옵니다.
- 가져온 타일을 개인판의 빈칸에 알맞은 형태로 배치합니다.
- 먼저 배치한 사람이 해당 라운드에 승리합니다.
위의 규칙을 자바스크립트로 구현하기 위해서 먼저 아래 세가지를 구현해보기로 하였습니다.
- 캔버스에 네모 모양 타일 배치
- 타일을 마우스 드래그로 위치 이동
- 네모 모양 목표에 동일한 모양의 네모 타일을 드래그로 이동시켜 인접한 위치에 도달했을 때 네모 모양 목표로 이동
시작 코드는 아래와 같습니다.
// index.js
const canvas = document.querySelector('canvas');
const ctx = canvas.getContext('2d');
const init = () => {
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
}
document.addEventListener('DOMContentLoaded', () => {
init();
})
캔버스에 네모 모양 타일 배치
캔버스에 네모 모양의 타일을 랜덤한 모양과 위치에 배치하는 기능을 구현하였습니다. 캔버스에 네모를 그리기 위해서는 strokeRect 메서드를 활용합니다. 인수는 순서대로 x, y, width, height를 받습니다. 그리고 이름에서도 알 수 있듯이 윤곽선을 가진 네모 모양을 그릴때 사용합니다. 생성 전 strokeStyle로 컬러를 지정할 수 있습니다.
strokeRect(x, y, width, height)
Math.random 메서드를 활용하여 x, y, width, height 모두 랜덤한 값으로 정의합니다. width와 height의 최소값은 50으로 정합니다.
const createRectangle = () => {
for (let i = 0; i < 5; i += 1) {
const x = Math.floor(Math.random() * 20) * 20;
const y = Math.floor(Math.random() * 20) * 20;
const width = Math.floor(Math.random() * 20) * 20 + 50;
const height = Math.floor(Math.random() * 20) * 20 + 50;
rectangleList.push({ x, y, width, height });
}
};
그리고 DOMContentLoaded 이벤트 핸들러에서 createRectangle 함수를 호출합니다.
document.addEventListener('DOMContentLoaded', () => {
init();
createRectangle(); // 추가
})
위에서 배치할 타일의 위치와 크기를 모두 정했기 때문에 이를 바탕으로 캔버스에 그려줄 차례입니다. 위에서 소개한 strokeRect 메서드를 사용합니다.
clearRect 메서드는 기존 위치에 존재하는 그림을 지울때 사용합니다. 캔버스는 기존 요소를 지우지 않으면 계속해서 누적되어 표현됩니다. 만약 타일을 마우스로 이동시켰을 때 clearRect를 사용하지 않으면 이동 경로를 따라 네모가 계속 추가될 것입니다.
또한 캔버스는 이미 한번 그려진 대상을 선택할 수 있는 기능이 존재하지 않습니다. 이 말은 네모를 그린 후 해당 네모만 선택하여 제거하는 기능이 존재하지 않습니다. 그렇기 때문에 캔버스의 모든 내용을 제거 후 다시 그리는 작업이 필요로 합니다.
📢 일부만 지우고 사용할 수 있는 경우도 존재합니다.
const draw = () => {
ctx.clearRect(0,0, window.innerWidth, window.innerHeight);
ctx.strokeStyle = 'black';
rectangleList.forEach(({ x, y, width, height }) => {
ctx.strokeRect(x, y, width, height);
});
}
추가적으로 타일을 이동시킬 네모 모양 목표를 그려줍니다. 이때 랜덤하게 생성된 타일이 목표 타일과 동일한 모양이 생성되지 않을 수 있기 때문에 목표 모양과 동일한 사각형도 또한 추가합니다.
let targetRectangle = null;
const createTargetRectangle = () => {
const x = 800;
const y = 300;
const width = Math.floor(Math.random() * 20) * 20 + 50;
const height = Math.floor(Math.random() * 20) * 20 + 50;
targetRectangle = { x, y, width, height };
// 목표 도형과 동일한 사이즈의 도형을 만들기 위한 코드
rectangleList.push({
x: Math.floor(Math.random() * 20) * 20,
y: Math.floor(Math.random() * 20) * 20,
width,
height
});
};
그리고 draw 함수에 네오 모양 목표를 그리는 코드를 추가합니다.
const draw = () => {
// ...
ctx.strokeStyle = 'red';
ctx.strokeRect(
targetRectangle.x,
targetRectangle.y,
targetRectangle.width,
targetRectangle.height,
);
}
마지막으로 DOMContentLoaded 이벤트 핸들러에서 createTargetRectangle 함수를 호출합니다.
document.addEventListener('DOMContentLoaded', () => {
init();
createRectangle();
createTargetRectangle(); // 추가
draw(); // 추가
})
다음에는 배치한 타일을 드래그로 이동시키는 것을 정리해보겠습니다.
'사이드 프로젝트 > 판교고' 카테고리의 다른 글
[판교고 - 기술체크] 1-3. 동일한 타일 여부 확인 (0) | 2023.05.15 |
---|---|
[판교고 - 기술체크] 1-2. 캔버스에 타일 드래그로 이동 (0) | 2023.04.25 |