루프 애니메이션 2편에서는 최소한의 구현을 진행했다. 이어 3편에서는 프레임을 만들어 움직이는 이미지의 동작을 구현해보자.
Canvas 좌표
영상, 캐릭터, 게임과 같은 콘텐츠 어플의 공통점은 '움직임'에 있다. 콘텐츠(게임,미디어) 어플은 항상 뭔가 움직인다. 아니 움직여야 한다. 특히 게임에는 동작이 전부라 할 정도로 움직임이 많다. 3D의 경우, 벡터, 오일러, 물리학(원운동,미분,역학계산 등..)의 개념까지 접목시켜야하기 때문에 게임엔진을 사용하지 않고 A부터 Z까지 제작하기에는 정말 쉽지않은 도전이다. 그나마 2D같은 경우, x, y축만 계산하면 되기 때문에 3D보다 간단하다.
하지만 아무리 간단한 2D 콘텐츠 프로그래밍이라 할지라도 다음 3가지 부분에 대한 이해가 필요하다.
1) Canvas 메서드(canvas 이해)
2) 이미지 소스, 캔버스의 x, y 좌표축 계산
3) 시간, 프레임 계산
html DOM에서 간단하게 사용했던 <img src=""></img>태그는 자바스크립트에서 new Image()내장객체를 기반으로 작동한다. 그리고 canvas는 자바스크립트의 내장객체를 활용해야하기 때문에 마크업 개발 수준(html태그)보다 한 단계 더 깊이 내려간다.
가령, canvas에서 drawImage()메서드를 통해 사용자가 원하는 이미지를 띄우기 위해서는 아래와 같은 문법을 지켜야 한다.
drawImage(image, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight)
x, y, width, height앞에 붙는 's'는 소스 이미지의 's'를 뜻하고, 'd'는 캔버스로 지정한 DOM의 영역을 의미한다. 위의 공식을 기반으로 현재 루프 애니메이팅에 사용하고 있는 소스 이미지를 살펴보자.
위의 일러스트의 크기는 1015(width) x 488(height) 픽셀이다. 그리고 물통이 걷는 동작을 위해서는 아래와 같은 부분의 이미지가 필요하다.
총 8장의 이미지가 걷는 동작을 의미한다. 즉, 0~7까지의 프레임이 필요하다. 그리고 총 8장의 이미지가 삭제 & 생성을 반복하며 x축 방향으로 이동을 할 경우, 움직이는 동작이 완성된다. 캔버스API는 1~8번까지 drawImage()메서드와 clearRect()메서드를 반복적으로 실행하면서 캐릭터의 각 움직임을 특정좌표축에 표시한다.
그런데 왜 모든 동작이 그려진 일러스트 이미지가 필요할까? 그냥 1~8번의 이미지가 그려진 각각의 파일을 준비하면 더 간단하지 않은가.
아마도 8장의 이미지의 삭제와 그리기를 반복적으로 실행하더라도 캐릭터 움직임이 가능하겠지만 개발자는 사용자 메모리 사용률을 고려해야 한다. 특히, 게임같은 경우(특히 웹 게임) 속도가 중요하기 때문에 위와같이 모든 동작이 그려진 일러스트 이미지 파일을 준비하고, 해당 이미지 파일에서 거리를 표시한 별도의 json파일을 사용하는 방법이 정석이다.
이미지의 위치를 표시하는 json파일은 아래와 같다.
[json파일 예시]
{"frames": [
{
"filename": "bucket0001.png",
"frame": {"x":519,"y":340,"w":81,"h":107},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":8,"y":15,"w":81,"h":107},
"sourceSize": {"w":140,"h":128},
"pivot": {"x":0.5,"y":0.5}
},
{
"filename": "bucket0002.png",
"frame": {"x":730,"y":106,"w":89,"h":102},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":9,"y":20,"w":89,"h":102},
"sourceSize": {"w":140,"h":128},
"pivot": {"x":0.5,"y":0.5}
},
...중략
위의 json파일에는 각 프레임별로 7개의 key와 value가 담겨있다. frame에는 일러스트의 위치를 표시하는 x, y값과 해당 x, y좌표축에서 이미지를 표시해야하는 가로, 세로 범위값(w, h)에 대한 정보가 저장되어 있다.
가령, frames[0]같은 경우 x:519, y:340의 위치에서 가로 범위가 81, 세로 범위가 107이다. 이를 일러스트 위치와 비교해보면 다음과 같다.
시작점이 되는 1번 프레임같은 경우 x, y좌표에서 "x:519, y:340"의 위치에 있다. 또, 위의 json파일에 있는 첫번째 frame키값의 w: 81, h:107의 크기는 1번 프레임의 이미지 크기다.
json파일의 spriteSourceSize의 정보는 캔버스에 위치하게 될 offset x,y값을 계산하는 데에 사용한다. 그리고 offset값은 캔버스에서 반복이 시작되는 위치를 의미한다. 관련 계산은 상황에 따라 만들 수 있는데, 이미지 소스의 가로, 세로의 값에 따라 시작점의 위치가 달라진다.
가령, offset.x,y값이 canvas DOM의 중심에 있다면 뜬금없이 위와같은 위치에서 시작할 수도 있다.
'웹개발 자료실 > 웹게임제작 Code' 카테고리의 다른 글
캔버스 루프 애니메이션 4편 『최종정리』 (0) | 2020.02.06 |
---|---|
캔버스 루프 애니메이션 3편 『프레임 계산』 (0) | 2020.02.05 |
캔버스 루프 애니메이팅 1편 『설계 및 최소구현』 (0) | 2020.01.31 |
캔버스 게임만들기 3편『state구현하기』 (0) | 2019.11.04 |
캔버스 게임만들기 2편『멀티 이미지 넣기』 (0) | 2019.11.02 |
댓글