노무현 대통령 배너

AS3.0 getDefinitionByName() 메서드를 이용한 라이브러리 자원 이용 – AS2.0 attachMovie 대응

by on 6.25, 2009, under AS3.0 API

blue_swf_iconAS2.0 시절, 프레임에서 신나게 코딩할때 라이브러리 패널에 링키지 네임을 준 무비클립을 attachMovie() 메서드를 이용해 스테이지에 불러와서 자유롭게 사용할 수 있었습니다.

AS3.0 에 들어와서는 라이브러리 패널의 링키지는 사용할 수 없지만 클래스 네임을 부여하여 별도의 클래스 파일을 만들지 않고도[01] new ClassName() 을 하여 마찬가지의 기능을 수행할 수 있습니다.

그런데 new ClassName() 에서 ClassName 부분은 정확한 클래스 이름이 와야 하고, this["str"] 나 _root["str"] 같이 AS2.0에서 흔히 사용했던 레퍼런스 참조 방법을 new 연산자 다음에는 사용할 수 없으므로 AS3.0에서 new ClassName() 으로는 아래와 같은 AS2.0의 for 문을 이용한 동적인 attachMovie() 는 사용할수가 없습니다.[02]

0
1
2
3
4
5
6
//AS2.0의 동적 attachMovie 예시
var arr:Array = new Array( "메뉴1", "메뉴2", "메뉴3" )
var len:Number = arr.length;
for ( i = 0; i < len; i++ )
{
	 attachMovie( "mc", "mc"+i, i )
}

그럼 어떻게 해야할까요?

먼저 라이브러리 패널에 있는 무비클립 심볼의 속성창을 열고 아래와 같이 클래스 이름을 지정해 줍니다.
lib_properties
클래스 이름은 for 문의 i 값으로 호출할 수 있게끔 숫자를 붙여 순차적으로 지정합니다. 그리고,

0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
//AS3.0에서 라이브러리의 클래스 이름을 이용하여 무비클립을 동적으로 사용
for ( var i:uint = 0; i < 5; i++ )
{
	var ClassReference:Class = getDefinitionByName( "mc" + i ) as Class;
	var displayObj:DisplayObject = new ClassReference();
 
	displayObj.addEventListener( MouseEvent.CLICK, clickHandler );
	displayObj.name = "mc" + i;
	displayObj.x = i * 51;
 
	addChild( displayObj );
}
 
function clickHandler( e:MouseEvent ):void
{
	trace( e.currentTarget.name )
}

이렇게 getDefinitionByName() 메서드를 이용해 Class의 레퍼런스로 캐스팅하고 new 연산자로 클래스를 호출하여 DisplayObject 객체에 담을 수 있습니다.
클래스가 다형성을 가지지 않고 이렇게 클래스의 이름을 이용하여 호출하는 주객이 전도가 된듯한 사용법은 객체지향 프로그래밍과는 약간 거리가 있는것 같긴 합니다만, 이런 사용법을 원하는 분들이 있고, 어도비에서도 이런 메서드를 제공하고 있으니 필요하다면 사용할 수 있는 거겠죠.

만약 buttonMode 등의 Sprite 속성을 사용해야 할 경우 DisplayObject 에는 해당 속성이 없으므로 아래와 같이 Sprite 로 캐스팅을 해야 합니다.

0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
for ( var i:uint = 0; i < 5; i++ )
{
	var ClassReference:Class = getDefinitionByName( "mc" + i ) as Class;
	var displayObj:DisplayObject = new ClassReference();
 
	//buttonMode 등의 Sprite 속성을 사용하려면 한번 더 캐스팅
	var instance:Sprite = displayObj as Sprite;
	instance.buttonMode = true;
 
	instance.addEventListener( MouseEvent.CLICK, clickHandler );
	instance.name = "mc" + i;
	instance.x = i * 51;
 
	addChild( instance );
}
 
function clickHandler( e:MouseEvent ):void
{
	trace( e.currentTarget.name )
}

관련 레퍼런스

  getDefinitionByName 예제 다운로드 - fla (Flash CS4에서 CS3 버전으로 저장, Flash 8 이하에서는 열리지 않습니다) , swf

* Loader 를 통해 로드한 다른 swf 의 라이브러리 자원 또는 클래스를 사용하는 방법은 “AS3.0 로더(Loader)로 불러온 다른 swf 의 클래스 사용하기” 를 읽어보세요.

이 글을 복사해서 퍼가시는건 허용하지 않습니다. 글의 주소를 다른곳에 알려주시는 것은 환영합니다.
  1. 정확하게는 컴파일 타임에 자동으로 클래스 파일이 생성됩니다. 그러나 개발자가 이에 관여할 필요는 없습니다. []
  2. new this["mc"+i]() 이런식으로 될리가 없다는거죠. []

관련된 글

:, , , , , , , , , , , , , ,

4 Comments for this entry

  • FlaskNo Gravatar

    다형성을 이용해 클래스를 짜야 하는건가요..? 하지만, 라이브러리로 불러온 이미지는 어찌할 수 가 없지 않나요? 비트맵 데이터를 상속하던데;; 다형성이 잘 이해가 되질 않네요;; 어따가 써먹어야 할 지도 모르겠더군요..

    • 세계의끝No Gravatar

      다형성과는 그닥 관계 없고요.
      결국 원하는 것은 같은 기능을 하는 다른 모양새의 클래스, 또는 그 반대가 되겠죠? (전자일 것으로 확실시 됩니다만…)

      쉽게, 동일한 조건으로 for문을 돌리는 예시를 들어보죠.
      for 문이 돌아가면서 얻을 수 있는건 무엇입니까? 결국 i 값이잖아요.
      무비클립으로 만든 클래스에 1프레임부터 n 프레임까지 원하는 모양을 그려 넣고 i 값으로 프레임을 이동하게 하면 동일한 효과를 얻을 수 있겠죠.

      이 방법이 마음에 안든다면…

      라이브러리에 기존 스타일대로 linkage 네임 주듯이 mc1, mc2, mc3… 스타일로 클래스 이름을 순서대로 정의한 무비클립을 하나의 클래스에 배열로 가져온 후, 역시 숫자값 i를 이용해…
      addChild( _array[ i ] ); 해도 되겠죠.

      위의 두 가지 방법은 정말 단순한 해결 방법에 불과할 테고요. 상상하기 나름 거의 무한대의 방법이 존재할 수 있습니다. 굳이 디자인 패턴 같은것을 언급하지 않아도 말이죠. ^^

      (본문과 별로 관계 없어보이는 Flask 님의 질문과 그에대한 저의 답변은 http://cafe.naver.com/flashdev/45310 으로부터 이어진 내용이기 때문이란걸 이 댓글을 보시는 다른 분들에게 알려드립니다.)

  • 세계의끝No Gravatar

    이글과 거의 동일한 성격의 포스팅을 RSS 를 읽다가 발견하여 덧붙입니다.
    http://www.emanueleferonato.com/2011/03/31/understanding-as3-getdefinitionbyname-for-all-eval-maniacs/

Leave a Reply

Looking for something?

Use the form below to search the site:

Still not finding what you're looking for? Drop a comment on a post or contact us so we can take care of it!

Meta