본문 바로가기
블로그 이미지

방문해 주셔서 감사합니다! 항상 행복하세요!

  
   - 문의사항은 메일 또는 댓글로 언제든 연락주세요.
   - "해줘","답 내놔" 같은 질문은 답변드리지 않습니다.
   - 메일주소 : lts06069@naver.com


Html 캔버스/Html 캔버스 에니메이션

HTML Canvas 퍼즐(puzzle)

야근없는 행복한 삶을 위해 ~
by 마샤와 곰 2022. 3. 30.

 

캔버스로 구현해본 퍼즐 입니다.

퍼즐은 그림을 나누어서 구역을 맞추는 게임 입니다.

 

Html canvas로 구현하기 위해서는 먼저 사각형을 그리는 방법과, 대입된 이미지 값 에서 주어진 좌표 크기만큼 가져오는 방법을 알아야 쉽게 다가갈 수 있습니다.

가장 먼저 작업한 것은 바로 구역을 나누는 행위 입니다.

가장 쉽게구현 할 수 있는 방법이 사각형 이므로 사각형 모양을 그려주기 위해 2중배열을 적용합니다.

 

위 2중배열에서 변수 j값은 x좌표의 거리를 위해 사용되었고, 변수 i 값은 y좌표 거리를 위해 사용 되었습니다.

또한 정사각형을 그려주기 위해서 cubeSize라는 변수를 사용하여 주었습니다.

이를 먼저 1차적으로 표현하면 아래 사진과 같은 모양을 그릴 수 있습니다.

각각 구역을 나누어 줍니다.

 

사각형을 그리는 것은 매우 쉬운 일 입니다.

캔버스에서의 rect 함수를 사용하면 쉽게 그릴 수 있습니다.

여기서 고민해야 되는 점은 바로 그려진 사각형에서의 이미지 데이터를 가져오는 행위 입니다.

캔버스에서는 getImagerData라는 함수를 활용하면 "시작x, 시작y, 가져올 넓이, 가져올 길이" 를 순차적으로 받아서 이미지 정보를 가져올 수 있습니다.

calculateImage(data){
    let imageData  = this.ctx.getImageData(data.x, data.y, data.boxWidth, data.boxHeight);
    return imageData;
}

 

그러므로 이러한 정보는 데이터를 관리할 배열이 필요하게 됩니다.

사각형을 그려주는 기능에서 배열을 추가하여 데이터를 관리하게 하여 줍니다.

대략 아래와 같이 4각형을 그려줄 때 배열을 만들어주면 될 거 같습니다.

makeBox( (pos)=>{
    dataArray.push(pos);
    drawRect(pos.x, pos.y, boxWidth, boxHeight, gridOption);
});

 

다음으로는 드래그 앤 드랍 기능 입니다.

퍼즐기능에서는 사용자는 드래그 앤 드랍을 통해서 그림을 맞추기 때문에 마우스다운, 마우스업, 마우스 무브 이벤트를 정의한 뒤 우선순서를 정하여 그려주도록 합니다.

#1. 마우스가 다운되었다.
#2. 마우스가 다운되었는데 움직인다 
 1) 기본 나누어진 영역을 지우고 다시 그립니다.
 2) 기본 영역이 그려지고 나면, 다운된 영역정보를 가져와 무빙하는 모습을 그려 줍니다.
#3. 마우스가 다운되었는데 움직였고 업 되었다.
 1) 일이 끝난 것 이므로 정답여부를 확인한다.
 2) 정답이 맞다면 색상을 추가한다.
 3) 전부 지우고 다시그려준다.

 

마우스의 이벤트를 가져오는 것은 자바스크립트에서 제공하는 addEventLisner 함수를 통해서 일괄적으로 타입별로 지정 할 수 있습니다.

마우스의 움직임에 따라 clientX값과 clientY값을 가져와서 캔버스의 position에 따른 값을 제거한 뒤에 사각형 이벤트를 구하는 공식을 사용하면 무브, 다운, 업 에 대한 이벤트를 쉽게 정의 할 수 있습니다.

 

여기서 구현하기 조금 어려운 것이 #2번 입니다.

순서에 맞추어서 캔버스를 지우고, 그리고를 반복 해 주어야 하기 때문 입니다.

가장 먼저 캔버스의 기본을 그려주고나서, 마우스의 커서의 clientX값과 clientY값을 가져와서 사각형을 그려주어야 드래그하는 모습을 표현할 수 있습니다.

아래와 같은 개념을 가지고 만들어 주면 됩니다.

캔버스.addEventListener(MOVE하는경우, event=>{
    //#1. event객체에서 event.clientX, event.clientY값을 가져옵니다.
    //#2. 캔버스 전체를 지웁니다.
    //#3. 캔버스 기본 내용을 다시 그려줍니다.
    //#4. #1에서 구한 좌표값에 대해서 사각형을 그려줍니다.
})

 

마지막으로 마우스가 위치에 도달하여 마우스가 업 되는 경우에는 드래그앤드랍 행위가 종료된 것 이므로 정답여부를 판별하면 됩니다.

가장 처음 배열을 선언하여 준 영역들은 고유의 인덱스를 가지고 있습니다.

그러므로 자기가 지금 위치한 영역의 인덱스 값과, 고유의 인덱스 값이 일치한지를 판별하면 됩니다.

자세한 코드와 기능은 아래 제 깃허브에서 확인가능 합니다. ^^

 

위 3단계를 거치고 나면 아래와 같은 모습의 나름 퍼즐맞추기 기능이 완성 됩니다.

섞기 기능을 통해 무작위로 바꾸어 줍니다.

 

움짤처럼 섞는 기능까지 더해주면 그럴싸한 기능이 완성됩니다.

각 코드별 기능 및 내용은 전체 소스코드를 참조하여 주세요.

아래 깃허브에 올린 소스코드를 통하여 위 사용된 기능을 전부 확인하실 수 있습니다.

https://github.com/TaeSeungRyu/sample/tree/main/그림 맞추기(퍼즐) 샘플

 

GitHub - TaeSeungRyu/sample

Contribute to TaeSeungRyu/sample development by creating an account on GitHub.

github.com

 

실제 동작하는 모습은 마찬가지로 아래 제 깃허브에서 확인가능 합니다.

https://taeseungryu.github.io/sample/sampleView/puzzle/index.html

 

 

위 모든 내용이 웹(web)에서 동작하는 캔버스(canvas)로 이루어진 내용 입니다.

 * 플래쉬, 액션스크립트, 유니티 같은 응용 프로그램이 아닙니다~

이상으로 HTML Canvas 퍼즐(puzzle)에 대해서 살펴보았습니다.

문의사항이나 궁금한 점은 언제든 댓글 또는 메일로 연락주세요~ 👻

 

반응형
* 위 에니메이션은 Html의 캔버스(canvas)기반으로 동작하는 기능 입니다. Html 캔버스 튜토리얼 도 한번 살펴보세요~ :)
* 직접 만든 Html 캔버스 애니메이션 도 한번 살펴보세요~ :)

댓글