본문 바로가기

Actionscript3.0

타임라인에서 일어 나는 동작을 알려주는, TimelineWatcher

Flash에서 MovieClip을 이용한 작업을 하다 보면 MovieClip에서 일어나는 동작을 코드상에서 알아 내서 이벤트를 발생 시켜야 하는 경우가 있다. 예를 들어 다음과 같은 Timeline이 있을때 재생헤드가 30 frame에 도달 할때 이 동작을 알아 내어 코드를 실행 시켜야 하는 경우가 있다.


이럴 경우 30 frame에 dispatchEvent를 사용하여 MovieClip을 가지고 있는 객체에 이벤트를 전달해 주는 방법을 사용할 수 있다.
dispatchEvent(new Event("playheadreached");
MovieClip에서 전달한 이벤트는
this.addEventListener("playheadreached",headreachedHandler);
private function headreachedHandler(e:Event):void{ // 코드 실행 }
를 통해 전달 받을 수 있다. 하지만, 이 방법은 반드시 Timeline에 코드를 입력해야만 가능한 방법이다. 많은 Flash 개발자들이 Timeline상에 코드를 입력하는 방법이 매우 비효율 적이라는 것을 느끼고 있을 것이다. 왜냐 하면 타입라인에 입력된 코드를 찾기 위해 낭비 하는 시간이 굉장히 많기 때문이다. 그래서, AS3.0에서는 addFrameScript 라는 메소드를 제공해 주고 있다.
adobe에서 제공하는 "AS3.0 Document"에는 이 메소드가 나와 있지 않지만 상당히 유용한 메소드 이다. 사용 방법은 다음과 같다.

package {

	import flash.display.MovieClip;

	public class FrameTest extends MovieClip{
		public function FrameTest()
		{
			this.addFrameScript("29",onFrameHandler);
			
		}		
		private function onFrameHandler():void
		{
			trace("reached");
		}
	}
	
}
Document class를 FrameTest라고 지정했을때, MainTimeline에 있는 재생헤드가 30frame에 위치하면 onFrameHandler 함수가 호출 된다. 주의해야 할 점은 30frame에 위치 했을때 함수를 실행 시키기 위해서는 this.addFrameScript("29",onFrameHandler); 게 해야 한다는 점이다. 29frame을 지난 직후에 메소드가 실행 되는 방식이기 때문이다. 또한 해당 타임라인이 존재 하지 않으면 이 메소드는 실행 되지 않는다.
addFrameScript는 상당히 직관적이고, 간편한 타임라인 컨트롤 방법을 제공해 주고 있다. 하지만 좀 더 간편한 타임라인 컨트롤을 지원해 주는 클래스가 있어 소개하려고 한다. 얼마 전에 Adobe Flash professional 커뮤니티에서 흥미 로운 기술 문서를 보았다. 이 기술 문서의 내용이 오늘 소개하려고 하는 클래스 이다.

타임라인에서 일어 나는 동작을 알려주는, TimelineWatcher

TimelineWatcher는 addFrameScript와 같은 타임라인 이벤트를 관리 해 주는 클래스 이다. EventDispatcher를 상속 받고 있기 때문에 내부적으로 dispatchEvent를 통해 타임라인의 위치를 전달해 주고 있다.


예를 들어 위와 같은 타임라인 모션이 있다고 하자. 그리고 Document class는 WatcherTest로 지정 한다.

package {
	
	import flash.display.MovieClip;
	import flash.text.TextField;
	
	import com.refunk.events.TimelineEvent;
	import com.refunk.timeline.TimelineWatcher;
	
	public class WatcherTest extends MovieClip {
		
		public var ball:MovieClip;
		
		private var timelineWatcher:TimelineWatcher;
		private var output:TextField;
		private var loops:uint = 0;
		
		public function WatcherTest() {
			super();
			stop();
			output = new TextField();
			addChild(output);
			timelineWatcher = new TimelineWatcher(this);
			timelineWatcher.addEventListener(TimelineEvent.LABEL_REACHED, handleTimelineEvent);
			timelineWatcher.addEventListener(TimelineEvent.END_REACHED, handleTimelineEvent);
			gotoAndPlay(1);
		}

		private function handleTimelineEvent(e:TimelineEvent):void {
			switch (e.type) {
				case TimelineEvent.LABEL_REACHED:
					output.text = "label: " + e.currentLabel + "\nloops: " + loops;
					break;
				
				case TimelineEvent.END_REACHED:
					loops++;
					if (loops > 10) {
						stop();
						timelineWatcher.removeEventListener(TimelineEvent.LABEL_REACHED, handleTimelineEvent);
						timelineWatcher.removeEventListener(TimelineEvent.END_REACHED, handleTimelineEvent);
						timelineWatcher.dispose();
						timelineWatcher = null;
					}
					break;
			}
		}
	}
}
		
우선 TimelineWatcher를 생성하고, 파라미터로 MovieClip 객체를 넘긴다. 그리고 TimelineWatcher에 이벤트리스너를 등록한다. TimelineWatcher가 캡쳐 할 수 있는 이벤트는 두가지 이다.

TimelineEvent.LABEL_REACHED : 타임라인에 Label 값이 있는 곳에 재생헤드가 위치해 있으면 호출 되는 이벤트 이다.
TimelineEvent.END_REACHED : 재생헤드가 타임라인의 처음부터 끝까지 돌았을때 호출되는 이벤트이다.
 
 위의 코드에서는 LABEL_REACHED END_REACHED 모두 handleTimelineEvent를 호출 메소드로 등록하고 있다. 같은 메소드라도 전달되는 이벤트의 종류가 같기 때문에 e.type을 이용하여 이벤트를 구분하고 각각에 맞는 이벤트를 처리 할 수 있다. 그리고 TimelineEvent.END_REACHED 이벤트를 이용해서 타임라인이 10번 돌았을때 LABEL_REACHED , END_REACHED removeEventListener 해주고 TimelineWatcher의 dispose 메소드를 이용하여 내부적으로 돌아 가고 있던 ENTER_FRAME 이벤트를 해제해 준다. (TimelineWatcher.as 를 참고)  ENTER_FRAME 이벤트 자체가 상당히 CPU 사용량이 크기 때문에 이벤트가 모두 종료된 후에 dispose 메소드를 반드시 호출해 줘야 한다. addFrameScript가 내부적으로 어떻게 구현되어 있는지는 모르겠으나, TimelineWatcher가 보다 더 유용하게 사용될 수 있는 클래스인거 같다.

  Flash는 타임 라인이라는 강력한 기능을 가지고 있다. 타임 라인이 존재 한다는것은 표현을 좀 더 자유롭게 할 수 있는 도구를 가졌다고 할 수 있다. 그러나, 디자이너는 너무 타임라인에 의존하는 프로젝트를 진행하고 있고, 개발자는 Flash를 Flash답게 사용하지 않고, Flex같이 사용하는 경향이 강하다. 타입 라인을 좀 더 자유롭게 사용할 수 있도록 도와주는 addFrameScript나 TimelineWatcher를 통해 좀 더 효율적인 업무 협업을 할 수 있겠다는 생각이 들었다. 익숙하지 않은 상태에서 다루기는 쉽지 않겠지만, 간단한 AS 구조이니 만큼 TimelineWatcher 나 TimelineEvent 클래스 구조도 살펴보는걸 추천한다.



TimelineWatcher에 대한 기술문서

예제 다운 로드