터치팡팡(a.k.a개미잡기) 개발강좌(5) - 캔버스에 개미를 움직여 보자2.

3 minute read

html5의 캔버스(canvas)를 이용하여 터치팡팡게임을 만드는 과정을 소개합니다. a.k.a 개미잡기
완성된 게임은 터치팡팡 <- 링크를 통해 확인할수 있다.




캔버스위에 개미를 움직여 보자(2)

저번시간에 개미를 비율에 맞게 그리는것 까지 해 보았다.

  • 개미의 머리 방향이 위로 되어 있다 오른쪽으로 움직이고 있으니 오른쪽을 바로보게 하자.
  • 개미 이미지 3개를 준비했으니 움직이면서 두번째 세번째이미지로 변경하면서 애니메이션 효과를 주자

이 두가지를 해보겠다.

머리 방향 바꾸기

먼저 개미머리 방향을 고친 코드펜을 보자.
(개미가 보이지 않는다면 우측하단에 return 버튼을 눌러보자)

See the Pen canvas 009 by mnmsoft (@mnmsoft) on CodePen.

추가된 부분을 살펴보자.

ctx.resetTransform();
ctx.beginPath();
ctx.translate(x + img.width / 2, 30 + img.height / 2);
ctx.rotate((Math.PI/180) * 90);
ctx.translate(-1 * (x + img.width / 2), -1 * (30 + img.height / 2));

새로운것이 많이 나왔다.
먼저 아래 소스를 보자.

이미지의 각도를 변경하기 위해서 이미지만 각도를 변경시킬수가 없다.
캔버스 판을 변경을 해야 한다.

translate함수는 캔버스의 좌표를 변경해주는 함수이다. 기본적으로 캔버스의 좌표는 좌측 최상단이 0,0이다. 캔버스의 기본 좌표를
x = 이미지의 x좌표 + 이미지가로사이즈의 반
y = 이미지의 y좌표 + 이미지세로사이즈의 반
으로 변경한다.

이미지가로사이즈의반 또는 이미지세로사이즈의 반은 이미지의 중점을 이야기 하므로 캔버스 좌표를 이미지가 그려질 가운데로 오게 한다.

rotate 함수는 캔버스를 돌리는 함수이다. 다시 말하지만 이미지를 돌려서 그리는 방식이 없기 때문에 캔버스의 중점을 이동하고 캔버스를 돌려야지 이미지를 돌려서 그릴수 있다.

다음 다시 translate함수가 호출되는데 각도를 돌린다음에는 다시 원점을 복귀 하기 위해서이다.

정리하면 원점을 옮기고 캔버스를 돌린다음 다시 원점을 이동한다. 그런다음에 drawImage 함수를 통해 이미지를 그리면 된다.

그런데 이렇게 끝내고 나면 각도가 틀어져 있는 상태이기 때문에 문제가 발생한다.
그래서 소스의 윗부분에 보면 resetTransform 함수가 호출된것을 볼수 있다. 이 함수는 변경된정보를 초기화 하는 함수이다.

내용을 처음 보면 캔버스에 이미지 회전해서 그리는게 복잡하게 느껴질텐데 캔버스는
원시적으로 하나하나 모두 제어 할수있는 장점이 있는반면에
같은말로 하나하나 모두 제어해야 한다는 단점이 있는거 같다.

대부분 각도를 틀거나 리소스를 변형을 주기 위해 이런식으로 사용하기 때문에 자주 쓰다 보면 익숙해 질것이다.

관련하여 위 처리를 하기 위한 함수를 하나 구현해도 좋다. 필자는 이런 함수를 만들어 두고 사용하고 있다.

  function angleDrawImg(ctx,angle,img,x,y,width,height){

	ctx.resetTransform();

	ctx.translate(x + img.width / 2, y + img.height / 2);
	ctx.rotate((Math.PI/180) * angle);
	ctx.translate(-1 * (x + img.width / 2), -1 * (y + img.height / 2));

	ctx.drawImage(img, x , y , width , height);

	ctx.translate(x + img.width / 2, y + img.height / 2);
	ctx.rotate((Math.PI/180) * -1 * angle);
	ctx.translate(-1 * (x + img.width / 2), -1 * (y + img.height / 2));

	ctx.resetTransform();
}

소스의 흐름대로
간단하게 설명하자면 모든변화를 초기화 하고
중점을 이동하여 각도를 돌리고 다시 중점을 복귀 하고
이미지를 그리고
다시 중점을 이동하여 각도를 복귀하고 다시 중점을 복귀 하고
모든변화를 초기화 한다.

이미지 교체하기

(개미가 보이지 않는다면 우측하단에 return 버튼을 눌러보자)

See the Pen canvas 010 by mnmsoft (@mnmsoft) on CodePen.

일단 이전 강좌에서 설명한 부분들 함수로 뺄 내용들을 빼냈다. 이미지 비율에 맞게 이미지 사이즈 조절을 하기 위해 아래 imgReSize 함수를 사용하였고.

function imgReSize(img,width){
  let tempWidth = img.width;
  img.width = width;
  img.height = img.width * img.height / tempWidth;
}

이미지 각도를 변경하기 위해 angleDrawImg 함수를 사용하였다.

function angleDrawImg(ctx,angle,img,x,y,width,height){

	ctx.resetTransform();

	ctx.translate(x + img.width / 2, y + img.height / 2);
	ctx.rotate((Math.PI/180) * angle);
	ctx.translate(-1 * (x + img.width / 2), -1 * (y + img.height / 2));

	ctx.drawImage(img, x , y , width , height);

	ctx.translate(x + img.width / 2, y + img.height / 2);
	ctx.rotate((Math.PI/180) * -1 * angle);
	ctx.translate(-1 * (x + img.width / 2), -1 * (y + img.height / 2));

	ctx.resetTransform();
}
  if (x % 10 <= 3)
    img = img1;
  else if (x % 10 <= 6)
    img = img2;
  else
    img = img3;
    
  angleDrawImg(ctx,90,img,x,30,img.width,img.height);

그런다음 개미를 움직이기 위해 사용하는 x 변수를 이용하여
10으로 나눈 나머지 값이 3보다 작거나 같으면 (0,1,2,3) 첫번째 이미지 10으로 나눈 나머지 값이 6보다 작거나 같으면 (4,5,6) 두번째 이미지 10으로 나눈 나머지 값이 9보다 작거나 같으면 (7,8,9) 두번째 이미지 로 표현되게 수정하였다.

마무리

이렇게 개미의 머리방향을 바꾸고 이미지교체도 해보는 내용을 진행해봤다.

다음에는 개미가 곡선으로 움직이게 해보자

그럼 다음에 또 봐요~!

Leave a comment