이번에는 결과물 부터 시작합니다!
아래는 live.com에 오늘 다룰 예제를 테스트해 본 것입니다.
그간 정지 화면 캡쳐만 했는데 움직이는 예제이니 만큼 무려 동영상 캡쳐를 했습니다!


모처럼 동영상 업로드 기능도 있는 티스토리를 활용하기 위해 동영상으로도 다시 한번 우려먹고!

이번 회에는 좀 더 유용한 기능을 추가해봤습니다.
위의 결과물에서 보이는 것처럼 배경 DIV 위에 캐릭터 이미지가 있고 MouseMove 이벤트를 통하여 캐릭터가 마우스를 쫒아갑니다. 또 MouseMove 이벤트가 발생하지 않으면 즉, 커서가 멈춰있거나 화면 밖으로 나가고 일정 시간이 지나면 캐릭터가 -유령처럼- 사라집니다. 다시 커서가 움직여서 MouseMove가 발생하면 다시 커서를 쫒아갑니다.

뭐, 내용만 놓고 보면 아무짝에도 쓸모 없는 개짓이죠?
하지만 이벤트 핸들링과 타이머, 그리고 애니메이션의 기초를 시작하기엔 참 좋은 예제가 될 것입니다.
저는 현업 웹프로그래머가 아니라 이걸 만드는데만 해도 몇 시간 동안의 디버깅 스트레스에 시달렸다구요 :(
(웹 디버깅 너무 귀찮습니다. ㅠ.ㅜ)


작성에 필요한 요소들을 하나씩 짚어보죠.

1. 배경 DIV
개짓의 최소 사이즈를 보호하면서 배경 색상을 가지고 있어 일종의 stage 역할을 합니다.
또한 MouseMove 이벤트는 이 공간 안에서만 발생하면 되겠지요.

2. 캐릭터 애니메이션
마우스를 쫒아다니는 캐릭터로 보통때엔 숨겨져 있다가 배경에 커서가 올라오면 커서를 쫒아다닙니다.

만약 캐릭터가 한쪽 방향만 보고 움직이지도 않는다면 커서를 쫒아올때도 생동감이 없을 것입니다.


위와 같이 좌/우를 바라보고 있어야 커서의 위치에 따라 조금 더 자연스러운 움직임을 보여주겠고 2 프레임의 단순한 움직임이지만 단순한 위치 이동에도 어떤 동작을 하고 있는 것처럼 보이는 효과를 얻을 수 있습니다.

또 하나 생각해 볼 것은 어떤 구간 동안 일정한 동작을 무한히 혹은 비교적 짧은 시간동안 반복하는 애니메이션이라면 그걸 시간에 따라 스위칭되는 프로그래밍을 할게 아니라 GIF로 만들어 버리면 간단하다는 점입니다.

만약 왼쪽을 보고 있는 캐릭터 이미지 2장, 오른쪽을 보고 있는 캐릭터 이미지 2장 이렇게 만들고 내부 타이머로 각 이미지를 교차시킨다면 정말 쓸데없는 코드 낭비 아니겠어요? :)

3. 이벤트 핸들러
배경 DIV에서 발생하는 MouseMove 이벤트를 코드로 전달해야 하는 데요, JavaScript/DOM에서는 이벤트 핸들러를 해당 객체에 직접 바인딩 하는 방법을 사용합니다.
JavaScript가 편리한 점 중에 하나가 함수도 객체로 취급할 수 있다는 것 같습니다. (물론 다른 많은 객체 지향언어도 가능합니다.)

이벤트 핸들러의 바인딩은,
object.onMouseMove = fnEventHandler;
와 같은 문법으로 아주 쉽게 처리할 수 있습니다.
object에서 MouseMove라는 이벤트가 발생(on)하면 fnEventHandler라는 함수가 자동으로 호출이 되고 발생된 이벤트의 추가 정보는 핸들러 함수 내에서 event 라는 키워드로 접근할 수 있습니다.

또 C와는 다르게 클래스 내부의 멤버 함수도 별도의 처리 없이 그냥 함수 이름으로만 바인딩이 가능하니 쉬울 수 밖에요.

4. 타이머를 통한 프로시저 처리
위의 세가지 요소만으로도 커서를 따라오는 -따라온다기 보단 커서에 붙어다니는- 캐릭터를 만들 수 있습니다. 그렇게만 만들면 재미가 없고 좀 더 나은 동작을 위해 커서가 멈춰도 일정 시간동안 커서를 계속 쫒아오도록 했습니다.

데스크탑 애플리케이션을 만들때야 스레드 하나 추가해주면 간단하게 해결될 일이지만 스레드가 없는 환경에서는 두 가지 방법을 선택할 수 있습니다.

메인 프로시저에서 무한히 루프를 돌면서 모든 종류의 이벤트와 정보를 프레임 단위로 처리하는 방법과 짧은 인터벌의 타이머를 통해 메인 루틴을 처리하는 방법인데요, 이 시나리오에서는 타이머를 선택하였습니다.

전자의 경우 프로세싱에 관한 모든 사항을 메인에서 꽉 잡고 있고 루프가 최대속도로 동작하므로 비교적 빠르게 처리가 가능한 반면 무한루프이기 때문에 아무 처리가 없을 때에도 CPU 자원을 소비하는 단점이 있습니다. 주로 CPU의 자원을 몽땅 투자해야 하는 수준의 게임을 만들때 사용합니다.

후자의 경우 타이머의 주기별로 프로세싱을 하므로 CPU 부담이 거의 없고 객체위주로 처리를 수행하게 됩니다. 단점은 아무래도 전반적인 프로세싱 속도는 메인 루프에 비해 느리고 객체 중심 처리를 하다 보면 코드가 여기저기 흩어지게 되는데 디버깅할 때 상당히 애먹습니다.

타이머 방식을 선택한 이유는 개짓이 혼자서 리소스를 다 먹어야 할 이유도 없고 그래서도 안되기 때문입니다. 지금 만들고 있는 것은 어느정도 인터랙티브한 요소가 있어서 프로세싱이 상당히 많이 들어가긴 하지만 굳이 메인 루프가 꽉 잡아야 할 정도로 버겁진 않죠.

또 다른 이유는, 객체를 중심으로 하는 코드를 만들어 보고 싶기 때문입니다.
이 예제의 세부 코드들은 그런 객체지향과는 거리가 좀 있지만 차차 고쳐나갈 테니까요.


너무 하나마나 한 소리만 한 감이 있네요;
게다가 저는 웹 프로그래머도 게임 프로그래머도 아닌데 잘 알지도 못하면서 주절거린 것 같기도 하고...
제 설명에 문제가 있다면 가차 없이 지적해 주세요!!

글이 길어져서 예제 코드 설명은 다음 파트로 넘깁니다~ :)

신고
Posted by gongdo


티스토리 툴바