[AS3] SelectRectangleExample

Project/Programming 2007. 8. 2. 11:47
예전에 마리오클링거만이 만들었던 Marching Ants Rectangle을 AS3 버전으로 수정하고 Object select 기능을 추가하여 MouseEvent.MOUSE_DOWN, MouseEvent.MOUSE_MOVE,MouseEvent.MOUSE_UP 이벤트를 통해서 오브젝트를 선택할 수 있도록 만들어 보았다. 윈도우 바탕화면에서 처럼 아이콘들을 선택하고 선택한 아이콘들을 이동하는 기능으로 확장 가능할 것으로 생각된다. 오늘은 여기까지만...;;













    

설정

트랙백

댓글

[AS3] cacheAsBitmap 적용시 고속처리를 위한 팁

Programming/ActionScript 3.0 2007. 7. 31. 07:48

인스턴스를 표시할 때 구형과 같이 Rectangle형태를 갖고 있지 표시오브젝트의 경우 그래픽이 포함되지 않은 부분(투명한 부분)에 색을 넣으면 알파 블랜딩 처리를 생략하여 조금 고속으로 표현할 수 있다. 인스턴스의 투명 부분에 색을 입히려면 각 인스턴스의 프롭퍼티에 있는 opaqueBackground 에16 진수 칼라를 지정하면 된다.

입혀진 배경색에 해당하는 부분은 마우스 이벤트를 받지 않는 영역이다.








import flash.display.Sprite;

var circle:Sprite = new Sprite();
circle.graphics.beginFill(0x0000FF);
circle.graphics.drawCircle(40, 40, 40);

circle.cacheAsBitmap = true;
circle.opaqueBackground = 0xFFFFFF;

circle.addEventListener(MouseEvent.MOUSE_OVER, function(evt:Event){
        trace("over");
});

addChild(circle);
    

설정

트랙백

댓글

[AS3] 이벤트 핸들러 함수에 파라미터 넘겨주기

Programming/ActionScript 3.0 2007. 7. 31. 07:10

로컬 변수를 선언하고 있는 함수 내에서 새롭게 함수를 동적으로 작성하면 로컬 변수를 보관 유지하는 함수를 만들 수 있다. 인수로부터 건네 받는 변수도 로컬 변수이므로 보관 유지가 가능하다.

function createFunc(param1) {
        var param2 = 2;
        var param3 = 3;

        return function() {
                trace(param1, param2, param3);
        }
}
var func = createFunc(1);
func(); // 1 2 3

이러한 형태를 이용하면 이벤트에 건네주는 함수에 파라미터를 넘겨 줄 수 있다.

var count = 0
stage.addEventListener (Event.ENTER_FRAME,enterFrameHandler(count));

function enterFrameHandler (count) {
        return function (event){
                trace("count :"+count);
                count ++;
        }
}

결과 :
count :0
count :1
count :2
count :3
.
.
.

    

설정

트랙백

댓글

[AS3] 클래스 오브젝트 취득

Programming/ActionScript 3.0 2007. 7. 31. 06:06

문자열로부터 클래스 오브젝트를 취득
문자열로부터 클래스를 인스턴스화하려면 getDefinitionByName() 함수를 사용한다. 인수에 클래스명을 문자열로 지정하면 클래스 오브젝트를 반환한다.

 
변수의 내용의 형태를 문자열로 취득
변수의 내용의 형태를 조사하려면 getQualifiedClassName() 함수를 사용한다. 인수에 변수를 대입하면 내용에 어떤 형태의 데이터가 들어가를 문자열로 반환한다.






var mc : MovieClip = new MovieClip(); 
var value_name : String = getQualifiedClassName(mc);
trace(value_name); // flash.display::MovieClip

var class_obj : Object = getDefinitionByName(value_name);
var mc2 : MovieClip = new class_obj();
trace(mc2); // [object MovieClip]


 

import flash.display.DisplayObject;
import flash.display.Sprite;
import flash.utils.getDefinitionByName;


var bgColor:uint = 0xFFCC00;
var size:uint = 80;

getDefinitionByNameExample();

function getDefinitionByNameExample() {
        var ClassReference:Class = getDefinitionByName("flash.display.Sprite") as Class;
        var instance:Object = new ClassReference();
        instance.graphics.beginFill(bgColor);
        instance.graphics.drawRect(0, 0, size, size);
        instance.graphics.endFill();
        addChild(DisplayObject(instance));
}
    

설정

트랙백

댓글

[AS3] hitArea 제거 방법

Programming/ActionScript 3.0 2007. 7. 29. 06:35
Sprite를 생성할 경우 보통 hitArea는 그 안에 있는 표시오브젝트가 된다. 이 때문에 아래 버튼을 놓고 위에 hitArea를 갖고 있는 DisplayObject를 올려놓을 경우에는 아래에 있는 버튼에 이벤트가 발생하지 않는다. 이는 캡처단계와 버블링 단계가 도달할 수 없는 서로 다른 오브젝트이기 때문이다.

이럴 경우 아래에 있는 버튼에 마우스 이벤트를 발생하기 위해서는 다음과 같은 방법으로 해결할 수 있다.

내부 그래픽이 있는 overDisplayObject를 맨 앞(index 최상)에 놓고 아래에 버튼이 있을 때

1. overDisplayObject.mouseEnabled = false;
2. overDisplayObject.hitArea = new Sprite();

2 번과 같이 적용하게 되면 overDisplayObject의 hitArea을 그래픽이 없는 Sprite로 대체 하기 때문에 overDisplayObject의 hitArea가 사라져 아래에 있는 버튼에 마우스 이벤트를 보낼 수 있다. 1번의 경우는 DisplayObjectContainer에 있는 속석을 사용한 방법으로 오브젝트에서 마우스 이벤트를 받지 않도록 설정할 수 있다.



    

설정

트랙백

댓글

[AS3] 코드 길이를 줄여보자

Programming/ActionScript 3.0 2007. 7. 29. 05:10

DisplayObjectContainer의 배치에 사용되는 메소드들은 반환형으로 DisplayObject를 반환한다. 이를 통해서 DisplayObject생성, 배치, 참조의 보관 유지를 한 줄로 해결할 수 있다.

 
아래 소스와 같이 사용하면 특정 DisplayObject를 원하는 인덱스 위치로 이동할 때 코드 라인을 줄일 수 있다.









import flash.display.Sprite;

var spriteAry:Array = new Array();

for
(var i:uint;i<4;i++)
spriteAry.push(addChild(new Sprite()) as Sprite);

var lastChild:Sprite = spriteAry[spriteAry.length-1];

// lastChild를 맨 앞면으로 이동.
addChild(removeChild(lastChild));
trace(getChildIndex(lastChild));

// lastChild를 맨 뒤로 이동.
addChildAt(removeChild(lastChild), 0);
trace(getChildIndex(lastChild));

    

설정

트랙백

댓글

[AS3] Create Number

Project/Programming 2007. 7. 28. 17:34
웹상에서 본 효과가 재미있어서 확장하여 숫자 DisplayObject를 만들어 보았다...

















    

설정

트랙백

댓글

[AS3] INFINITE의 네비게이션 제작

Programming/ActionScript 3.0 2007. 7. 23. 12:32

AS3를 공부하면서 처음으로 실질적으로 사용 가능한 네비게이션을 블로그의 INFINITE 메뉴에 있는 프로젝트에 적용해 보았다. AS3의 개념이 확실히 마음속에 들어오지 않은 터라 여러가지로 만들면서도 공부하게 되었는데, 초기 유스케이스 및 UML을 그리지 않고 머리 속에서 이렇게 하면 되겠지 싶어서 하다 보니 구조를 잘못 설계하여 중간 지점부터 다시 코드 작성을 했다. 단기적인 작업을 많이 해왔던 터라 초기 구조설계에 소홀히 했던 것은 앞으로 조금씩 문서화 작업을 통해서 기초설계에 좀더 신경을 써야 할 것 같다.

그 동안은 필요해서라기 보다는 AS3의 개념적인 부분과 기능적인 부분을 닥치는 대로 자료를 찾아 공부하다가 실질적으로 필요에 의해서 제작하다 보니 여러 가지로 어려움이 많았던 것 같다.

구조로 보면 AS2에서는 굳이 그렇게 할 필요가 없는 것들이 AS3에서는 그렇게 해야하는 것으로 바뀐 것들도 있고 AS2에서 어떠한 방법을 구현하기 위해서는 우회적인 방법을 동원해야 했던 것이 AS3에서는 간단한 방법으로 되는 경우도 있다.

메뉴는 xml데이터를 불러들여 메뉴를 정렬하게 되는데 깊이는 3으로 세팅되었으나 xml에 따라서 무한 깊이까지 가능할 듯 싶다. AS2가 아닌 막 공부를 시작한 AS3로 제작하다보니 AS2에서 설계하던 머리 속 생각과는 다른 구조로 제작할 수 있고, 또 그렇게 해야 한다는 것을 느끼게 된다.

보기에는 간단해 보이는 네비게이션이지만 클래스 구조에 어느 정도 생각이 필요했다. INFINITE 안에는 앞으로 공부하면서 제작되는 샘플들을 수록할 듯 싶다. 아직 담으려는 컨텐츠에 대해서는 깊이 있게 고민은 해보지 않았다.

Container의 구조는 왼쪽 메뉴를 통해서 버튼을 클릭했을 때 화면 중간에 컨텐츠를 보여주는 형태가 될 것 같다. 예전에 AS2버전으로 작업했던 UI&CL:ab 프로젝트의 구조와 비슷할 듯 싶다.

    

설정

트랙백

댓글

[AS3] XML 클래스의 length() 메소드는 왜...

Programming/ActionScript 3.0 2007. 7. 21. 01:57
xml을 로드하여 네비게이션을 만들던 중에 AS3의 xml에 있는 메소드 length()는 왜 getter, setter 접근자 함수를 사용하지 않았는지 의문이 든다. 보통 Array에서 흔히 사용하는 length는 set, get 접근자 함수를 사용하여 캡슐화 원칙에 준하는 사용하기 편리한 인터페이스를 제공하고 있는데 AS3에서 Dot syntax를 사용하게 된 XML 클래스에서는 유독 일반 메소드 형태로 length() 메소드를 제공하고 있다.

배열과 같은 형태로 사용하지만 배열이 아니라는 것을 암묵적으로 알려주기 위해서 그러했는지 아니면 다른 의도가 있는지 모르겠다. 아무튼 lenfth()를 lenfth로 표기하면서 값이 찍히지 않아서 한참을 물끄러미 바라보다가 이 글을 쓴다.





레퍼런스 내용

length ()  메서드    
AS3 function length():int

XML 객체의 경우 이 메서드는 항상 정수 1을 반환합니다. XMLList 객체에 값이 하나만 포함된 경우 XMLList 클래스의 length() 메서드는 1을 반환합니다.

반환값
    int — 모든 XML 객체에 대해 항상 1을 반환합니다.

    

설정

트랙백

댓글

[AS3] UIScrollBar 클래스 응용

Programming/ActionScript 3.0 2007. 7. 20. 12:43
AS3에서 제공하고 있는 UIScrollBar 컴포넌트의 경우는 스크롤 대상이 되는 scrollTarget이 TextField로 한정하고 있다. ActionScript로 RIA 형태의 프로젝트를 진행하다보면 ScrollBar를 많이 사용하게 되는데 이때 TextField를 대상으로 하는 ScrollBar도 많이 사용하지만 가장 사용빈도가 놓은 것은 특정 무비클립(AS3에서는 DisplayObject)에 Object들을 나열하여 스크롤 형태를 제공하는 경우가 많이 발생한다.

AS3에서 제공하고 있는 component의 경우에는 플래시 폴더에 보면 swc파일이 아닌 as파일로 정리되어 있으니 컴포넌트가 어떻게 구성되어 있는지 시간 날때 확인해 보는 것도 괜찮을 것 같다.

C:\Program Files\Adobe\Adobe Flash CS3\en\Configuration\Component Source\ActionScript 3.0\User Interface\fl\controls

기존에 있던 UIScrollBar 그대로 사용하되 target이 되는 TextField를 DisplayObject 형태로 변형하였기 때문에 flash CS버전에서 제공하는 컴포넌트를 그대로 사용할 수 있게 하였다.


휠을 이용하여 스크롤할 경우에 익스플로러에서 포커스를 가져가버리는 문제가 있는데 패치가 되야 할 것 같다.

컴포넌트가 보이지 않는 문제는 파이어폭스의 문제나 flashplayer의 버전 문제가 아니라 엉뚱하게도 티스토리에서 기본적으로 플래시를 임베드 시킬때 생성하는 코드가 예전 방식으로 처리되고 있는 문제였다. 티스토리에서 자동 임베드 코드 생성시에 수정하여야할 부분이다...





    

설정

트랙백

댓글

[AS3] DisplayObject란

Programming/ActionScript 3.0 2007. 7. 20. 11:10
1. DisplayObject란 무엇인가?
AS2까지는 MovieClip이 모든 것을 처리할 수 있었으나 AS3에서는 기존의 MovieClip의 기능을 여러 개의 클래스로 분산해 놓았다.

1.1. 표시 오브젝트란

표시 오브젝트란 화면에 표시되는 모든 오브젝트라고 할 수 있다. 예를 들면 AS2의 MovieClip도 화면에 표시되므로 표시 오브젝트라고 할 수 있다. String 이나 Sound와 같은 클래스의 오브젝트는 그 자체로 화면에 표시할 수 없는 것들이기 때문에 표시 오브젝트라고 할 수 없다.

AS3에서는 MovieClip을 복수의 클래스에 분산시켰는데 타임 라인 기능이 없는 Sprite과 같이 MovieClip보다 적은 기능을 갖고 있는 클래스도 있고 비트 맵을 표현하는 Bitmap 클래스, 텍스트를 표시하는 TextField 클래스 등이 있다. Sprite와 같은 클래스를 이용하면 MovieClip을 사용하는 것보다는 전체적으로 퍼포먼스를 향상 시킬 수 있다. 이유는 AS3이전에는 MovieClip 자체에서 거의 모든 기능을 포함하고 있었기 때문에 MovieClip 하나만을 보더라도 묵직했지만 그것을 기능별로 분류하여 오브젝트 자체가 가벼워 졌기 때문이다. 실제로 사용하게 되는 표시 오브젝트 클래스들은 아래와 같은 클래스들이 있다.

AVM1Movie, Bitmap, MorphShape, Shape, StaticText, Video, SimpleButton, TextField, Loader, Sprite, Stage, MovieClip

1.2. 표시 오브젝트 컨테이너란

표시 오브젝트는 “화면에 표시되는 모든 오브젝트” 라고 하였지만 정확하게는 “화면에 표시할 수 있는 모든 오브젝트” 라고 할 수 있다.

new로 만든 표시 오브젝트만으로 화면에 표시되지는 않는다. 표시 오브젝트는 표시 오브젝트 컨테이너에 넣어야만 화면에 표시된다. 아래에서 이야기 하겠지만 표시 오브젝트 컨테이너에 있는 addChild나 addChildAt 메소드 등을 이용해서 컨테이너에 표시 오브젝트를 추가하는 행위로서 화면에 표시된다. 표시 오브젝트 컨테이너가 될 수 있는 클래스는 아래와 같은 클래스들이다.

Loader, Sprite, Stage, MovieClip

여기서 표시 오브젝트 컨테이너는 그 자체가 표시 오브젝트라는 것을 알 수 있다.
AS3의 이전 버전에서 사용하던MovieClip이 상자 구조를 취할 수 있던 것처럼 이러한 클래스도 상자 구조를 취할 수 있다.

1.3. 표시 리스트란
이와 같이 컨테이너 화면에 표시되고 있는 오브젝트의 리스트를 표시 리스트라고 한다. swf 1개의 최상위에는 1개의 Stage 오브젝트가 있다. 이것이 스테이지의 최상위 컨테이너가 된다.

스테이지로부터 표시 오브젝트는 트리 구조를 갖게 되며 컨테이너가 될 수 없는 표시 오브젝트는 리프 노드(그 이상 분기하지 않는 것)이며
컨테이너는 리프 노드, 또는 브랜치 노드(그 이상 분기 가능한)가 된다.

1.4. 표시 오브젝트의 실체
표시 오브젝트는 보통 변수 같아서 하나의 표시 오브젝트의 실체는 오로지 하나다. 표시 오브젝트를 복수의 컨테이너에 addChild 할 수 없으며 동일 컨테이너에 addChild 했을 경우에도 컨테이너에서는 한 번 삭제되어(이동했다는 표현이 더 적절하겠다) 컨테이너의 맨 위(depth)에 추가된다. 표시 오브젝트 컨테이너에는 addChild와 반대의 기능을 하는removeChild라는 메소드를 가지고 있다. 이것은 이름대로 컨테이너로부터 표시 오브젝트를 삭제하는 메소드다. removeChild 메소드는 컨테이너(표시 리스트)로부터 지정한 표시 오브젝트를 제외할 뿐, 메모리에서 제거되는 것이 아니라는 것을 잊어서는 안 된다. 표시 오브젝트를 더 이상 사용하지 않을 경우에는 removeChild와 함께 별도로 delete 연산자로 표시 오브젝트를 삭제하여야만 가비지 컬렉터에 의해 메모리 회수 대상이 될 수 있다.

2. DisplayObject 클래스와 DisplayObjectContainer 클래스의 관계

표시 오브젝트의 개념을 토대로 표시 오브젝트의 기본이 되는 2개의 클래스를 보면서 좀 더 구체적으로 이야기하면 다음과 같다.

2.1. DisplayObject 클래스 개략
모든 표시 오브젝트는 DisplayObject 클래스를 상속하고 있다.(자세한 상속 관계는 레퍼런스를 참조) 간단하게 말하면 모든 표시 오브젝트에 공통의 성질(프롭퍼티나 메소드)은 DisplayObject 형을 갖고 있는 것이다. 예를 들면 x 나 y ,height ,alpha 등은 공통 항목으로서 DisplayObject 클래스가 가지고 있는 것이다.

MovieClip을 잘 다루기 위해서 레퍼런스를 보는 경우 AS2 까지는 MovieClip만을 보면 되었으나 AS3부터는 기본이 되는 DisplayObject의 프롭퍼티와 메소드를 알아 둘 필요가 있다. 반대로 말하면 DisplayObject의 취급을 알아 두면 모든 표시 오브젝트를 컨트롤 할 수 있다. (DisplayObject 속성에 한하여) 레퍼런스를 참조할 때는 DsplayObject의 항목을 우선적으로 확인해 볼 필요가 있다. DisplayObject 자체는 표시를 위한 기능을 가지고 있지 않으므로 사용자 클래스를 만드는 경우는 DisplayObject의 서브 클래스를 확장하여 사용하면 된다.

2.2. DisplayObjectContainer 클래스 개략
Sprite나 MovieClip은 컨테이너가 될 수 있다고 이야기 했는데 그것들은 DisplayObjectContainer 클래스를 상속하고 있기 때문이다. 컨테이너를 조작하는 메소드나 프롭퍼티(addChild등)는 DisplayObjectContainer 클래스가 공통으로 가지고 있는 기능이다. 물론 DisplayObjectContainer 클래스는 DisplayObject 클래스를 상속하고 있다.
「심도」의 취급에 대해서도 DisplayObjectContainer (프롭퍼티•메소드)로 관리하게 된다. Sprite나 MovieClip을 취급하는 경우는 이러한 클래스 레퍼런스를 참조할 필요가 있다.

2.3. AS3에서의 심도 관리는 어떻게 되나
AS3 이전의 액션스크립트에서는 depth나 getNextHighestDepth을 자주 사용하였지만AS3에서는 이러한 메소드는 사라졌다. 하지만「심도」와 같은 개념은 남아 있는데, AS3에서는 해당 컨테이너가 몇 번째에 위치해 있는가를 나타낼 때 “인덱스 위치” 라는 개념으로 설명할 수 있다.

인덱스 위치는 0에서 부터 시작해 증가하는데 0은 가장 안쪽(아래)이 되며 수치가 큰 만큼 앞(위)에 표시된다.

인덱스 위치는 기존에 사용하던 심도의 개념처럼 고정된 것이 아니다. 컨테이너 내에서 표시 오브젝트가 추가되거나 위치가 조정 되면 다른 자식 오브젝트도 자동적으로 인덱스 위치가 조정된다. 심도와는 달리 인덱스 위치는 불연속적인 성격을 가지지 않으며 절대적으로 연속적이다.
만약 0, 1,2라는 인덱스 위치를 가지고 있는 3개의 오브젝트가 하나의 컨테이너 안에 있을 경우 인덱스 1에 있는 오브젝트를 인덱스 0으로 이동할 경우 AS3 이전의 스크립트에서는 0 뎁스 위치에 있는 오브젝트가 삭제되고 1뎁스에 있는 오브젝트가 0뎁스로 이동하고 기존의 1뎁스는 소멸하면서 중간에 1뎁스에는 오브젝트를 갖고 있지 않은 불연속적인 성격을 갖고 있었으나 AS3부터는 인덱스 1위치를 0위치로 이동할 경우 자동적으로 0위치에 있던 오브젝트는 인덱스 1위치로 이동하게 되므로써 연속적인 위치를 유지하게 된다.

2.4. 컨테이너의 조작
좀 더 구체적으로 이야기 하기 위해서 DisplayObjectContainer의 메소드나 프롭퍼티를 몇 개 소개하면 다음과 같다. (자세한 것은 레퍼런스 참조)

•addChild / addChildAt 메소드
컨테이너에 표시 오브젝트를 추가한다. addChild는 항상 맨 위에 자식 오브젝트를 추가한다.(인덱스 위치의 마지막) addChildAt을 사용하면 특정 인덱스 위치를 지정할 수 있다.

•setChildIndex / swapChildren / swapChildrenAt 메소드
컨테이너의 자식 오브젝트의 인덱스 위치를 변경한다. swapChildren, swapChildrenAt은 2개의 자식 오브젝트를 지정하고 위치를 바꾼다. 전자는 인수로서 2개의 오브젝트를 지정하고 후자는 2개의 인덱스 위치를 지정해서 바꿀 수 있다.

•removeChild / removeChildAt 메소드
컨테이너로부터 표시 오브젝트를 삭제한다. removeChild는 직접 오브젝트를 삭제하고(표시 리스트에서 제거)  removeChildAt은 인덱스 위치를 통해 삭제한다. 표시 오브젝트의 실체는 삭제되지 않으며 어디까지나 컨테이너로부터 제거될 뿐이다.(메모리 영역은 유지된다.)

•getChildAt / getChildByName 메소드
지정한 오브젝트를 돌려준다. getChildAt은 인덱스 위치를 통해 돌려주고 getChildByName은 오브젝트명을 통해서 지정한 오브젝트를 돌려준다. getChildByName의 경우는 해시검색을 진행하기 때문에 getChildAt 쪽이 getChildByName보다 처리속도가 빠르다.

•getChildIndex 메소드
지정한 오브젝트의 인덱스 위치를 돌려준다.

•contains 메소드
컨테이너 내에 지정한 오브젝트가 있을지를 조사하여 Boolean 값(true/false)를 돌려준다.
import flash.display.Sprite;
var sprite1:Sprite = new Sprite();
var sprite2:Sprite = new Sprite();
var sprite3:Sprite = new Sprite();
var sprite4:Sprite = new Sprite();

sprite1.addChild(sprite2);
sprite2.addChild(sprite3);

trace(sprite1.contains(sprite1)); // true
trace(sprite1.contains(sprite2)); // true
trace(sprite1.contains(sprite3)); // true
trace(sprite1.contains(sprite4)); // false
•numChildren 프롭퍼티
컨테이너에 포함되는 자식 오브젝트의 수를 돌려준다. (컨테이너명.numChildren - 1)로 하면 컨테이너의 맨 위의 인덱스 위치를 지정할 수 있다.

    

설정

트랙백

댓글

[AS3] ActionScript 3.0의 스텝 가이드

Programming/ActionScript 3.0 2007. 7. 14. 07:25
ActionScript 3.0 이행 스텝 가이드
R Blank
Adobe Flex 2와 Flash CS3 Professional에서 생성된SWF 파일을 실행하는 Adobe Flash Player 9는 Flash 플랫폼의 새로운 파워업을 구현한다고 할 수 있습니다. Flash Player 9를 이용하면 Flash 7이나 8로 제작한 프로젝트에 비해 최고30배 고속으로 실행되는 프로젝트를 제작할 수 있습니다.

Flash Player 9의 퍼포먼스가 큰 폭으로 향상한 이유는 Flash나 Flex 의 디벨로퍼가 기술한 코드를 해독하는 ActionScript Virtual Machine (AVM )을 새롭게 개발하고 있는 것을 들 수 있습니다. 또 ActionScript 3.0은 테크놀로지의 좋은  파트너라고도 할 수 있습니다 ActionScript의 최신 버전 ActionScript 3.0 에도 대폭적인 개량이 이루어지고 있습니다. ActionScript 3.0은 구버전보다 훨씬 파워풀함과 동시에 ActionScript 언어를 ECMAScript 국제 규격에 완전하게 준거시킨 버전이기도 합니다. 그 때문에 ActionScript 3.0은 종래의 Flash 디벨로퍼가 익숙했던 것 이상의 엄밀함이 요구됩니다.


알파치는 0에서 1의 범위에서 지정한다
기존의 ActionScript에서는 무비 클립의 알파 프롭퍼티를 0부터 100사이의 값으로 지정하고 있었지만 ActionScript 3.0에서는 0 부터 1 까지가 알파값의 범위가 됩니다. 이러한 변경은 그 자체가 별 것은 아니지만 ActionScript 3.0을 시작하는데 있어서 충분히 주의해 둘 필요가 있는 것이라고 할 수 있습니다. 디벨로퍼가 디버그 작업에 몇 시간을 낭비하거나 의지를 잃는 사태에 빠질 수도 있는 변경사항입니다.

이것과 같이 단순한 변경사항이 많이 있습니다. 예를 들어 지금까지 MovieClip 프롭퍼티로 사용되고 있었던 언더 스코아가 모두 삭제되어 있거나( 「_x 」는 「x 」, 「_width 」는 「width 」가 됩니다), Video 클래스의 attachVideo() 메소드가 보다 적절한 이름의attachNetStream() 으로 변경되어 있거나 합니다. ActionScript 3.0의 습득을 원한다면 ActionScript 테크놀러지 센터에 액세스 하는 것을 추천합니다.

무비 클립의 변경 사항

다음의 코드가 작동한다면 멋지지 않습니까?.

var mc:MovieClip = new MovieClip();

그렇습니다, ActionScript 3.0에서는 이 코드가 올바르게 기능합니다. 이것은 기존의 Flash 디벨로퍼에 있어서 가장 큰 개념상의 변경 사항이라고 할 수 있을지도 모릅니다. ActionScript 3.0 에는 새로운 표시 리스트가 있어서 이것이 Flash Player 위에 있으면서 여러분의 SWF 파일의 실질적인 물리 아키텍처를 구성합니다.

기존의 Flash에 있어서의 최대의 무거운 짐이라고 한다면 무비 클립이 SWF 파일상의 모든 물리 오브젝트의 친타입으로서 다루어지고 있던 것입니다. 이것은 모든 요소가 무비 클립이거나 모든 요소에 타임라인이 필요한 것이 아닌데도 말입니다. ActionScript 3.0에는 DisplayObject라는 이름의 새로운 클래스가 있어서 MovieClip은 단지 표시 오브젝트의 한 종류로서 존재합니다. 또 하나의 표시 오브젝트는 스프라이트입니다. 이러한 DisplayObject의 각 종류에는 다른 능력이 갖춰져 있습니다(각각 다른 자원을 이용합니다). 즉, 무비 클립에 대해서 할 수 있는 것과 스프라이트에서 할 수 있는 것이 각각 다릅니다.

위에서 보았던 코드가 무비 클립을 생성한다고 하여 이 무비 클립이 자동적으로 표시되는 것은 아닙니다. 무비 클립을 표시하려면 해당 DisplayObject 클래스를 스테이지 또는 다른 표시 오브젝트에 첨부할 필요가 있습니다. 무비클립(또는 모든 표시 오브젝트)을 어디에 배치할까는 addChild() 또는 addChildAt() 메소드를 이용해 Flash에 명시적으로 지시할 필요가 있습니다.

이것은 다양한 가능성이 있습니다. 예를 들어 지금까지의 Flash의 경우 무비클립은 특정의 타임 라인에 관련지을 수 있었기 때문에 무비클립을 다른 타임라인상으로 이동할 수 없었지만 앞으로는 removeChild()나 addChild()를 이용하여 표시 리스트내의 표시 오브젝트의 위치를 동적으로 변경할 수 있습니다(예를 들어, 프로젝트가 있는 부분의 타임 라인으로부터 무비 클립을 삭제하고 이것을 프로젝트내의 완전히 개별적인 무비 클립으로 이동 것이 가능합니다). 복잡하게 얽히는 타임라인의 문제점은 회피할 수 있을 것입니다.

_root 는 어디에?
위에서 설명한 변경사항을 바탕으로ActionScript 3.0에서는 _root의 개념도 없어졌습니다. 즉, SWF 파일의 메인 타임라인의 참조가 없어졌습니다(AS3에서는 메인의 타임라인을 유지할 필요성이 없어졌습니다). 또,  만능적으로 액세스 가능했던 Stage 클래스도 없어졌습니다.

그럼 ActionScript 3.0에서 이러한 개념이 어떻게 되냐하면 스테이지 또는 스테이지의 자식이 관련지을 수 있었던 표시 오브젝트는 각자, Stage로 불리는 해당 스테이지에 의해서 참조를 가지게 됩니다. 예전에 _root 로서 파악해 온 것은 향후 Stage 프롭퍼티로 참조할 수 있습니다.

새로워진 패키지
패키지로서 중요한 것은 허용량의 대소가 아니라 몇 개의 클래스를 포함할 수 있는가 하는 것입니다. 패키지와 일련의 클래스는 디벨로퍼가 코드를 정리하는 목적으로 이용할 수 있는 툴입니다. ActionScript 2.0의 패키지는 클래스 파일을 수용하기 위한 컴퓨터상의 폴더이며 코드를 정리하기 위한 편리한 툴 정도 였습니다. 그리고 각 파일에는 오로지 1개의 클래스 밖에 포함할 수 없습니다. 또한 클래스명과 파일명을 완전하게 일치시키지 않으면 안 된다고 하는 제약이 있었습니다.

그러나 AS3는 package 스테이트먼트를 이용해 ActionScript (.as ) 파일 내에서 정의 가능한, 진정한 의미의 패키지를 취급할 수 있게 됩니다. AS 파일에 패키지(또는 네스트화 된 복수의 패키지)를 수록하여 이 안에 1개 또는 복수의 클래스를 포함하는 것이 가능합니다.

이 변경이 프로그래머를 더 혼란스럽게 하는 것으로 보일지도 모르지만 실제로 이 새로운 코드 구조를 시험해 보면 그 유연성이 마음에 들 것입니다. 필자 자신도 이 기능이 코딩 체재에 얼마나의 영향을 미칠까에 대해서 회의적이었지만 작업을 진행하면서 클래스(특히, 순수한 데이터 클래스등)가 매우 간단하게 작성할 수 있게 된 것을 실감하고 있습니다. 패키지에 관한 이번 변경은 ActionScript 프로그래머에 의해 좋은 객체 지향프로그래밍 수법을 제시하는 것이라고 할 수 있겠습니다.

7 개의 주요 패키지/클래스
ActionScript 3.0의 클래스 파일을 사용하기 전에 알아야할 것은 지금까지 ActionScript에 내포되고 있던 일련의 Flash Player 클래스를 ActionScript 3.0에서는 명시적으로 import하지 않으면 안 된다는 것입니다. 만일 텍스트 필드를 작성하고 싶은 경우에는 다음의 예와 같이 텍스트 필드 클래스를 명시적으로 읽어들일 필요가 있습니다.

import flash.text.TextField;

또 텍스트 패키지의 모든 클래스를 읽어 들이고 싶은 경우에는 다음과 같이 기술합니다.

import flash.text.*;

import 스테이트먼트는 변경사항이 없기 때문에 ActionScript 2.0와 같은 방법으로 이용할 수 있습니다. 앞으로 import 스테이트먼트가 예전보다 자주 필요할 뿐입니다. 소정의 클래스를 명시적으로 읽어들이지 않으면 클래스 파일로 완성되는 것은 큰 폭으로 제한되게 됩니다.

ActionScript 3.0의 패키지와 클래스 파일이 익숙하지 않거나 어느 클래스가 필요하게 되는지를 고민하고 싶지 않은 경우는 다음의 7 개의 패키지를 기억해 두면 좋을 것입니다. 이 7개의 패키지에는 Flash 어플리케이션 또는 FLA 에 필요한 클래스의 대부분이 포함되어 있습니다(보다 프로패셔널적인 개발 방법으로서는 필요한 클래스만을 읽어들이도록 해 주세요).

import flash.net.*;
import flash.events.*;
import flash.display.*;
import flash.geom.*;
import flash.ui.*;
import flash.utils.*;
import flash.text.*;

document 클래스를 활용한다

document 클래스는 모든 디벨로퍼에 있어서 유익한 것이지만 특히 메인 타임라인에 1 프레임만을 배치하는 것과 같은 디벨로퍼에 있어서 가장 유용한 것입니다. Flash 어플리케이션을 코딩 할 때 디벨로퍼의 상당수는 FLA 의 단일 프레임에 모든 요소를 배치하여 불과 1행의 ActionScript를 이용하고 제작한 외부 클래스 파일을 호출하고 있습니다. 앞으로는 이 1행의 코드마저 불필요하게 되어 퍼블리시 설정의 다이알로그 박스에서나 스테이지가 선택 되고 있을 때의 프롭퍼티 패널상에서 직접 FLA 에 document 클래스(제작중의 FLA 에 대한 단일의 클래스 파일)을 할당할 수 있습니다.

이 클래스는 반드시 Sprite 또는 MovieClip을 계승하는 것이 필요합니다.(document 클래스이기 위해). 이 클래스의 constructor함수는 해당 SWF 파일의 읽기와 함께 자동적으로 불려 갑니다.

비트 맵 및 무비의 읽기 방법
loadMovie() 메소드(혹은 예전의 ActionScript로 말하면 MovieClipLoader() 클래스)는 대부분의 Flash 디벨로퍼에 있어서 빠뜨릴 수 없는 존재라고 할 수 있겠습니다. 여기에서는 Flash 9 컨텐츠에 Flash 무비 또는 비트 맵(JPEG ,PNG ,GIF)을 읽어들이기 위한 중요한 7행의 코드를 소개하기로 하겠습니다. 이하에 나타내는 코드는 스프라이트를 사용한 간단한 예지만 이 밖에도 다양한 변이를 생각할 수 있습니다.
var bgToLoad:String = "05092007.gif";
var bgLoader:Loader = new Loader();
var bgURL:URLRequest = new URLRequest(bgToLoad);
bgLoader.load(bgURL);

var bg:Sprite = new Sprite();
bg.addChild(bgLoader);
addChild(bg);
이 코드에서는 우선 Loader 오브젝트를 작성하고 미디어 파일에 포인트 한 URLRequest 오브젝트를 사용해서 외부 미디어의 읽기를 지시하고 있습니다. 이 때 미디어를 읽어들이게 하는 앞의 표시 오브젝트(bg)가 확실히 존재하는 것을 확인하고 이 코드는 메인의 타임 라인에 존재하게 되므로 맨 마지막 줄의 addChild에 의해서 bg 스프라이트를 스테이지상에 배치하고 있습니다.

XML의 읽기 방법
Flash 유저의 대부분이 외부 SWF 파일 또는 비트맵 읽기에 익숙한 것과 같이 무비에 XML을 사용하고 데이터를 읽어들이는  케이스도 빈번히 볼 수 있습니다. XML의 이용에 관해서는 ActionScript 3.0에서 비약적으로 편리한 기능이 많이 준비되어 있습니다. 이러한 편리한 기능에 접하기 전에 우선 XML 파일을 읽어들이기 위한 기본적인 코드를 소개해 둡니다.
var xmlSrc:String = "myData.xml";
var ur:URLRequest = new URLRequest(xmlSrc);
var ul:URLLoader = new URLLoader();

ul.addEventListener(Event.COMPLETE,dataLoaded);
ul.load(ur);

function dataLoaded(evt:Event):void
{
trace(evt.target.data);
}
이 코드에서는 우선 사용하고 싶은 XML 파일에 포인트 하는 URLRequest 오브젝트를 작성하고 그 다음에 URLRequest를 읽어들이는 URLLoader를 작성합니다. 그리고 COMPLETE 이벤트(XML 의 읽기 완료)의 청취자로서 dataLoaded() 메소드를 추가하고 있습니다. dataLoaded() 메소드 안에서는 이벤트 자체의 target 프롭퍼티의 data 프롭퍼티에 포인트 하는 것으로 XML을 trace 하고 있습니다.

비약적으로 편리하게 된 XML의 해석
이것으로 ActionScript 3.0의 훌륭한 XML 기능인 ECMAScript for XML (E4X ) 을 이용할 준비가 갖추어졌습니다(ActionScript 3.0은 국제적인 오픈 표준 규격의 ECMAScript 262에 완전 준거하고 있습니다). E4X의 자세한 해설은 다른 기회로 미룹니다만 데이터의 취급이 중요하게 대두되고 있고 ActionScript 3.0에서는 이 부분이 큰 폭으로 개선되고 있는 것을 고려하여 하이라이트를 소개하기로 하겠습니다.

ActionScript 2.0에서 디벨로퍼의 대부분이 XML의 읽기와 동시에 Flash 데이터에의 해석•변환을 실시하여 처리 시간으로서 프로세서에 큰 부담이 되었습니다. 그러나 ActionScript 3.0과 E4X를 이용하면 노드를 직접적으로 참조할 수 있어서 XML의 트리 구조를 파일 시스템과 같이 손쉽게 취급하는 것이 가능합니다.

Flash Player 9에서 주목하는 신기능
지금까지 소개한 내용을 참고로 하여 ActionScript 3.0에의 대한 우려가 어느 정도 해소되었다고 생각합니다. 다음은 컨텐츠 제작의 폭을 한층 더 넓힐 가능성을 숨긴 Flash Player 9의 몇 개의 신기능에 대해서 다루기로 하겠습니다.

우선 첫 번째는 풀 스크린 모드 입니다. 본래 이 모드는 비디오 컨텐츠 체험을 JavaScript에 손대는 일 없이 확충하는 목적으로 개발된 것이지만 비디오 이외의 모든 어플리케이션에서도 이용할 수 있습니다(다만, 키보드로부터의 입력은 무효화됩니다).

Flash CS3의 새로워진 비디오 재생 컴퍼넌트에 이 기능이 포함되어 있습니다. 지금부터는 ActionScript에 접하는 일 없이 간단하게 풀 스크린 대응의 비디오 어플리케이션을 개발하는 것도 가능합니다(이 경우 HTML 안의 embed/object 나 SWFObject 코드의 allowFullScreen 파라미터를 잊지 않고 true로 설정하는 것에 주의해 주세요).이 기능에 대해 자세한 것은 Tracy Stampfli 씨가 집필한 Flash Player 디벨로퍼 센터 기사 「Flash Player 9 의 풀 스크린 모드에 대해 」를 참조해 주세요.

또 하나의 주목 할만한 기능은 뮤직 투시기을 작성할 때 사용할 수 있는 오디오 스펙트럼 해석 기능 입니다. 새롭게 정비된 SoundMixer 클래스에는 computeSpectrum()라고 하는 이름의 메소드가 포함되어 있어서 이 메소드를 이용하는 것으로 음악을 수치화할 수 있습니다. 그리고 수치화된 데이터를 바탕으로 쿨한 오디오 애니메이션이나 뮤직 투시기를 작성할 수 있습니다. 이 기능을 소개하는 매우 효과적인 튜토리얼에 대해서는 Peter deHaan 씨의 블로그의 엔트리 를 참조해 주세요.

그리고 마지막으로...
이 기사를 마치기 전에 참고 정보를 수집하기 위한 가이드를 소개하고 싶지만 그 전에 우선 이번 완전히 새로운 언어가 도입되었음에도 불구하고 매우 포괄적인 Flash CS3 Professional 헬프 파일을 제작한 Flash 서포트 팀에 대해서 칭찬을 보내고 싶습니다.

ActionScript 3.0과 Flash CS3는 아직 신출내기 단계입니다. 따라서 아직 관련 자료가 그만큼 많지는 않습니다. 향후 자료가 증가해 갈 것은 틀림없습니다. 현시점에서의 퍼스트 스텝으로서는 ActionScript 3.0과 Flash에 관한 최신 또는 갱신판의 기사, 샘플, 퀵 스타트 튜토리얼 등이 다수 게재된 Flash 디벨로퍼 센터를 북마크하는 것을 추천합니다. 또 Adobe.com에서 공개중의Flash CS3 LiveDoc 및Flex 2 LiveDoc도 참조하도록 해 주세요.(이 기사에서도 반복하여 참조한 것처럼) 이것들은 계속적으로 갱신되는 헬프 파일을 포함한 유용한 자원이며 각 항목에 대해서는 아도브의 서포트 스탭이나 다른 디벨로퍼가 코멘트를 쓰는 곳도 준비되어 있습니다.

아울러 2006년 중순부터 ActionScript 3.0과 Flex 2에 관한 복수의 서적과 DVD 를 출판하여 Flash 커뮤니티에 공헌해 주셨던 Joey Lott 씨에 대해서 이 자리를 빌려 Flash 커뮤니티의 일원으로서 개인적인 사의를 표하고 싶습니다. 이러한 서적•DVD는 매우 알기 쉬운 참고 자료입니다. 그리고 Colin Mook 씨에 의한 「Essential ActionScript 3.0 」가 출판되는 것을 기다릴 뿐입니다.

어땠습니까.이 기사를 읽는 것으로 ActionScript 3.0의 개념 이해가 깊어지면 다행입니다. 여러분도 꼭 이 훌륭한 최신 테크놀러지를 경험해 보세요.

영문 포스트 주소 : http://www.adobe.com/newsletters/edge/may2007/articles/article6/index.html

    

설정

트랙백

댓글

[AS3] EventDispatcher의 이해

Programming/ActionScript 3.0 2007. 7. 13. 13:09
자료를 찾다가 AS3의 이벤트 모델에 대해 쉽게 설명된 자료가 있어서 내용 추가 및 수정하였다. AS2의 컴포넌트에서 사용했던 EventDispatcher는 AS3에서 모든 표시 오브젝트에서 사용하고 있는 EventDispatcher의 표준이 되었다. AS2에서는 addListener도 사용했으나 AS3에서는 좀더 구체적으로 Event를 dispatch 할 수 있는 EventListener만을 사용하고 있다.

AS3 이벤트 모델 개요
AS3의 이벤트 처리는 AS2의 이벤트처리와 조금 다른 것을 볼 수 있다.

1. 이벤트는 “전파”한다
AS3의 표시 오브젝트 DisplayObject으로부터 발생한 이벤트를 그 이벤트를 받은 오브젝트 뿐만이 아니라 다른 오브젝트에서도 리슨 할 수 있다.

발생한 이벤트(클릭되었다 등)는 상자가 된 오브젝트를 부모로부터 자식에게 자식로부터 부모에게 이벤트가 전해져 가는 모델을 채택하고 있다. 이 개념은 이벤트의 전파(event propagation)라 불린다. 이벤트는 트리 구조 안을 이동하면서 각층(노드)에서 대응하는 리스너가 있을지를 검사하고, 있을 경우에는 그 리스너를 실행하게 된다.

예를 들어, 아래와 같이 상자 구조가 있다고 했을 때 DisplayObject (Sprite)를 생각해 보면, Sprite mc_01의 안에 mc_02 라는 Sprite이 있고 그 안에 mc_03라고 하는 Sprite이 있는 구조로 되어 있다. 여기서 mc_03를 클릭한다고 했을 때 AS2에서는 mc_03에 리스너를 등록할 필요가 있었지만 AS3에서는 mc_03 뿐만이 아니라 mc_02와 mc_01라는 Sprite에 설정한 리스너로 mc_03에서 이벤트를 취급할 수가 있다.

 
[상자 구조 샘플]

이것을 적절히 사용하면 이벤트 처리를 집중화시키는 것이 가능하다 .예를 들면 mc_02 ,mc_03에 공통의 이벤트 처리를 하고 싶은 경우라면 각각의 오브젝트에 이벤트 리스너를 등록할 필요가 없다.

2. 전파의 종류
전파는 아래와 같이 3단계로 분류된다.

1. 캡처-단계
2. 타켓-단계
3. 버블링-단계

이벤트의 전파는 원래 DOM (문서 오브젝트 모델)에 대한 이벤트 모델로서 브라우저에 도입된 것이다. (Netscape의 「이벤트 캡쳐링」모델,  Microsoft의 「이벤트 버블링」모델) W3C에 책정되고 있는 이벤트 모델이나 DOM에 대해서는 더 많은 정보가 필요해서 생략한다. 그러나 그 구현 방법은 ActionScript의 이벤트모델과 매우 유사하기 때문에 간단하게라도 알아 두는 편이 도움이 될 것 같다.

3.  캡쳐-단계
AS3에서 제일 초기에 실행되는 것은 이 캡쳐-단계다. 계층 구조의 오브젝트를 검사(리스너가 있는지를 조사)해 가면서 발생한 이벤트에 대응하는 리스너가 있으면 실행하게 된다. 캡쳐-단계에서의 이벤트는 루트로부터 이벤트가 발생한 타겟을 향해서 전파해 나간다.

위 샐플로 이야기하면 mc_03이라는 무비클립이 클릭되었을 경우 타겟은 mc_01 ,mc_02의 순서로 이벤트의 검사하게 된다. 타겟이 되는 mc_03의 이벤트 검사는 캡쳐-단계에서는 포함되지 않는다.

4.  타겟-단계
두번째로 이벤트의 검사를 하는 것은 타겟 단계이다. 이벤트가 발생한 타겟 자체의 이벤트 리스너를 실행한다. AS2의 관점에서 생각하면 이 타겟 단계만 실행된다고 할 수 있다. ‘

5.  버블링-단계
마지막에 이벤트의 검사를 하는 것은 버블링 단계다. 캡쳐-단계와는 반대로 타겟으로부터 루트를 향해서 전파 해 나간다.

위 샘플로 말하면 mc_03이 클릭되었을 경우 타겟은 mc_02 ,mc_01의 순서로 이벤트의 검사를 한다. 타겟이 되는 mc_03의 이벤트 검사는 버블링 단계에서도 포함되지 않는다.

6.  리스너는 중복 실행되지 않는다
여기서 생각해볼 것은 위에서 캡쳐단계와 버블링단계에서 처럼 리스너가 이중으로 실행된다고 생각할 수 있겠으나 그렇지는 않다. AS3의 캡쳐단계에서 리스너는 디폴트로 무효가 된다. 즉, 실질적으로 타겟으로부터 시작해 루트를 향해서 이벤트가 전파 해 나갈 뿐인 것이다. 물론, 캡쳐단계에서 리스너를 유효하게 할 수도 있지만 그럴 경우에는 버블링 단계에서 리스너가 무효가 된다.
양쪽 모두의 이벤트를 유효하게 할 수도 있다 이는 아래에서 이야기한다.


AS3 이벤트 관련의 클래스, 메소드에 대해
이벤트의 전파를 어떻게 제어하는 지와 관련된 클래스나 메소드에 대해 살펴보면 다음과 같다.

1.  addEventListener 메소드
AS3의 표시 오브젝트인 DisplayObject는 EventDispatcher를 상속하고 있다. 따라서 DisplayObject인 모든 군은 addEventListener 메소드를 사용할 수 있다. 여기서 AS3의 EventDispatcher.addEventListener 의 문장구조를 보면 다음과 같다.
addEventListener(
type:String,
listener:Function,
useCapture:Boolean = false,
priority:int = 0,
useWeakReference:Boolean = false
):void
먼저 기본이 되는 인수 type과 listener에 대해서는 기존 AS2의 EventDispatcher 와 다르지 않다. type 은 이벤트 타입(이벤트의 이름, “click” 등)이다. listener는 리스너 핸들러 함수다. 이벤트가 발생하여 리슨 되었을 때에 실행되는 함수다. 나머지의 인수는 옵션인데 설정하지 않는 경우는 디폴트 값이 적용된다.

useCapture는 캡쳐-단계에 리슨을 실시할지의 Boolean 값이다. 디폴트 값은 false다. useCapture를 true로 설정했을 경우 그 리스너는 캡쳐-단계에 이벤트를 리슨 하게 되지만 반대로 버블링 단계에서는 이벤트를 리슨 하지 않는다.

양쪽 모두 리슨 하는 경우는 useCapture의 값을 true / false로 하는 2개의 이벤트 리스너를 등록할 필요가 있다. 또, 레퍼런스에 의하면 캡쳐 단계에서 이벤트를 리슨 하게 되면 계산 처리의 부하가 커진다고 하니 특별한 이유가 없을 때에는 디폴트 값 false로 해 두는 것이 좋을 것이다.

priority는 우선도를 나타낸다. 수치가 큰 것일 수록 선행 처리된다. priority 값이 같은 경우에는 등록된 순서대로 처리된다. 부의 값도 이용할 수 있으므로, 디폴트값(0)을 기준으로 우선도를 설정할 수 있다. 다만, 우선도의 높은 처리가 완료되고 나서 낮은 처리가 다시 시작되는 것은 아니다..

useWeakReference는 리스너에 의한 참조가 약참조인지 어떤지를 나타내는 Boolean 값이다. 디폴트는 false이고 이는 강참조를 나타낸다. useWeakReference의 값을 true로 했을 경우에는 리스너의 가베지 콜렉터로부터 회피된다. 이에 대한 내용은 전에 작성한 포스트에서 확인할 수 있다.

2.  Event 클래스(오브젝트)
AS2의 EventDispatcher는 리스너에게 건네지는 이벤트 오브젝트와 type 프롭퍼티는 Object형태로 전달되었다. 하지만 AS3에서는 Event 클래스가 준비되어 있고 그것을 확장한 여러 가지 서브 클래스가 있다. 예를 들면 마우스 이벤트용의 MouseEvent 클래스나, 키보드 이벤트용의 KeyboardEvent 클래스 등이다.

KeyboardEvent 이벤트는 조작된 키의 키코드를 가지는 등 각각이 잘 정리되어 있다. Event 클래스를 확장하여 자작의 커스텀 클래스를 만들 수도 있다. 이는 예전 포스트에서 이미 내용을 기술해 놓았다.

3.  Event 클래스의 프롭퍼티
이벤트 오브젝트의 베이스가 되는 Event 클래스의 프롭퍼티를 보면 다음과 같다.

bubbles 프롭퍼티는 그 이벤트가 버블링 할지를 나타내는 Boolean 값이다. 디폴트는 false이고 그 경우 이벤트는 버블링 하지 않는다. MouseEvent 등은 true로 설정되어 있고 버블링 단계도 기능한다. 서브 클래스마다의 bublles 프롭퍼티는 레퍼런스를 참조해야 할 것 같다.

cancelable 프롭퍼티는 이벤트의 디폴트 동작을 캔슬할 수 있을지의 Boolean 값이다. 디폴트 동작의 캔슬에 대해서는 전 포스트에서 기술 한 적이 있다. isDefaultPrevented 프롭퍼티는 캔슬이 끝난 상태인지 어떤지를 보존하는 Boolean 값이 된다.

currentTarget / target 프롭퍼티는 각각 타겟의 참조다. target은 이벤트가 발생한 오브젝트의 참조다. currentTaget은 이벤트가 전파 하고 있을 때 이벤트가 어디에 있는지를 나타낸다. 즉, 오느곳의 오브젝트로 리스너를 검사하고 있는지를 나타내어 그 오브젝트의 참조를 돌려준다. target 프롭퍼티는 하나의 이벤트 오브젝트로 공통이지만 currentTaget 프롭퍼티는 전파 하는 과정에서 변해간다.

eventPhase 프롭퍼티는 이벤트가 어느 단계에 있는지를 나타내는 정수치를 가지고 있다.
1 - 캡쳐-단계
2 – 타겟-단계
3 – 버블링-단계

type 프롭퍼티는 이벤트 타입을 나타내는 String 값이다. 예를 들면 "click" 이나 "mouseOver" 등. addEventListener 의 type 값과 조합된다. 리스너는 이 값을 지정하여 이벤트를 리슨 한다.

4.  이벤트는 타겟 단계 밖에 동작하지 않아?
캡쳐-단계와 버블링 단계가 일어나는 것은 DisplayObject 오브젝트만이다. AS2 같이 표시 되어 있지 않은(표시 리스트에 없다) 오브젝트로부터도 이벤트는 dispatch 된다. 예를 들어 “로드가 완료했다”등이라고 하는 것과 같은 이벤트에 대해서도 dispatch 및 청취자는 같은 구조를 취한다. 이러한 이벤트는 많은 경우 전파 할 필요가 없고 이벤트는 타겟으로 직접 플로우 한다.

5.  이벤트의 전파를 정지한다
Event 클래스에는 stopPropagation / stopImmediatePropagation라고 하는 메소드가 있다. 이것들을 이용하면 이벤트의 전파를 도중 캔슬할 수도 있다. 즉, 리스너 안에서 건네 받는 이벤트 오브젝트를 이용하여 그 이벤트의 전파를 멈출 수 있다.

stopPropagation 메소드는 그 이벤트의 전파 자체는 정지하지만 현재의 노드(검사중의 오브젝트)의 리스너는 모두 처리한다.
stopImmediatePropagation 메소드는 전파도 정지하고 현재의 노드의 다른 리스너도 처리하지 않는다.

6.  이벤트의 디폴트의 동작을 캔슬한다
많은 이벤트에는 이벤트 발생시에 디폴트로 실행하는 동작이 있다. Event 오브젝트의 cancelable 프롭퍼티가 true의 경우에 한해서 Event.preventDefault 메소드를 이용하면 이러한 동작을 캔슬할 수 있다.

아래는 레퍼런스의 내용이다.

「예를 들어, 유저가 텍스트 필드에 문자를 입력했을 경우 디폴트 동작에서는 문자가 텍스트 필드에 표시됩니다. TextEvent.TEXT_INPUT 이벤트의 디폴트 동작은 캔슬하기 위해 preventDefault() 메소드를 사용해 문자를 표시하지 않게 할 수 있습니다.」

7.  이벤트의 dispatch
이벤트의 dispatch는 AS2의 EventDispatcher와 같이 dispatchEvent 메소드를 실행할 뿐이다. 다만, dispatchEvent에 건네주는 인수가 AS2에서는 Object이고 AS3는 Event 오브젝트라는 것이 다르다.
새로 Event 오브젝트를 만들고 dispatchEvent의 인수로 건네주게 된다.

Event오브젝트의 constructor는 다음과 같은 문장구조를 갖는다.
Event(event_type:String, bubbles:Boolean, cancelable:Boolean)
bubbles 와 cancelable은 옵션으로 생략 할 수 있다. 간단한 dispatchEvent는 아래와 같다.

my_obj.dispatchEvent(new Event(MouseEvent.CLICK));


    

설정

트랙백

댓글

[AS3] SoundMixer를 이용한 스펙트럼

Programming/ActionScript 3.0 2007. 7. 12. 00:44

var s:Sound = new Sound();
var sc:SoundChannel;
var ba:ByteArray = new ByteArray();
var array:Array;

s.load(new URLRequest("sound.mp3"));
sc = s.play(0,1);
this.addEventListener(Event.ENTER_FRAME, spectrum);
function spectrum(event:Event) {
        var a:Number = 0;
        SoundMixer.computeSpectrum(ba,true,0);
        for (var i=0; i < 50; i++) {
                a = ba.readFloat();
                var num:Number = a*400;
                trace(num);
        }
}
 





기본적으로 as3에서 스펙트럼을 구현할 때 위와 같은 형태로 만들 수 있다. 크로스 도메인 정책 파일을 서버에 구현해 놓지 않으면 로드된 사운드의 데이터에 액세스할 수 없다. 이는 BitmapData의 경우도 같다.


아래는 샘플로 작업한 위 결과물의 코드다.

package{

import flash.display.Sprite;
import flash.display.SimpleButton;
import flash.events.Event;
import flash.events.MouseEvent;

import flash.media.Sound;
import flash.media.SoundMixer;
import flash.media.SoundChannel;

import flash.net.URLRequest;
import flash.utils.ByteArray;


public class SoundSpectrumTest extends Sprite {
        private var s:Sound;
        private var ba:ByteArray;
        private var mcAry:Array;
        private var main1:Sprite;
        private var sc:SoundChannel;
        private var recTotalNum:uint;


        public function SoundSpectrumTest() {
                s = new Sound();
                ba = new ByteArray();
                mcAry = new Array();
                main1 = new Sprite();
                sc = new SoundChannel();
                recTotalNum =300;
                addEventListener(Event.ADDED_TO_STAGE, initialize);
        }
        private function initialize(evt:Event):void {
                removeEventListener(Event.ADDED_TO_STAGE, initialize);
                loadSound();

        }
        private function setButtonEvent():void{
              play_mc.addEventListener(MouseEvent.CLICK, playHandler);
              stop_mc.addEventListener(MouseEvent.CLICK, stopHandler);

        }
        private function playHandler(evt:Event):void{
                sc.stop();
                createEnterFrame();
                sc = s.play(0, 10);
        }
        private function stopHandler(evt:Event):void{
                removeEnterFrame();
                sc.stop();
        }

        private function startSpectrumDisplay():void{
                var gap:uint = 1;
                for(var i:uint=0;i<recTotalNum;i++){
                        var mc:Rec = new Rec();

                        mc.x = i*(mc.width+gap);
                        mc.y = 230;
                        main1.addChild(mc);
                        mcAry.push(mc);

                }

                addChild(main1);
                main1.x = uint(stage.stageWidth/2 - main1.width/2);
                main1.y = uint(stage.stageHeight/2 - main1.height/2);
                createEnterFrame();
        }
        private function createEnterFrame():void{
                addEventListener(Event.ENTER_FRAME, leftSpectrum);
                addEventListener(Event.ENTER_FRAME, rightSpectrum);
        }
        private function removeEnterFrame():void{
                removeEventListener(Event.ENTER_FRAME, leftSpectrum);
                removeEventListener(Event.ENTER_FRAME, rightSpectrum);
        }
        private function loadSound():void {
                s.load(new URLRequest("sound.mp3"));
                s.addEventListener(Event.COMPLETE, loadedSound);

        }
        private function loadedSound(evt:Event):void{
                startSpectrumDisplay();
                setButtonEvent();
                sc = s.play(0, 1000);
        }
        private function leftSpectrum(event:Event):void {
                var left:Number;
                var leftNum:Number = 0;
                var leftTotalNum:Number = recTotalNum/2;

                SoundMixer.computeSpectrum(ba,true,0);

                while(leftTotalNum>=0){
                        left = ba.readFloat();
                        leftNum = left*400*sc.leftPeak;

                        mcAry[leftTotalNum].height = leftNum;
                        leftTotalNum--;
                }

        }
        private function rightSpectrum(event:Event):void {
                var right:Number;
                var rightNum:Number = 0;
                var rightTotalNum:Number = recTotalNum/2;

                SoundMixer.computeSpectrum(ba,true,0);

                while(rightTotalNum<recTotalNum){
                        right = ba.readFloat();
                        rightNum = right*400*sc.rightPeak;

                        mcAry[rightTotalNum].height = rightNum;
                        rightTotalNum++;
                }
        }
}
}
    

설정

트랙백

댓글

[AS3] 스코프

Programming/ActionScript 3.0 2007. 7. 9. 22:25

기본적으로 ActionScript의 컴파일러는 현재 스코프 내에 사용하고자 하는 변수를 찾을 수 없을 때에는 상위 스코프에서 찾게 된다. 아래와 같은 코드를 AS2에서 실행해보면 다음과 같이 출력되는 것을 알 수 있다.












// AS2 코드 결과
var _this:String = "global";
trace(_this);  // 출력 :  global

function subScopeFunction() {
        trace(_this);  // 출력 : global
        var _this:String = "local";
        trace(_this); // 출력 : local
}
subScopeFunction();
trace(_this);  // 출력 : global

하지만 AS3에서는 사정이 좀 다르다.

// AS3 코드 결과
var _this:String = "global";
trace(_this);  // 출력 :  global

function subScopeFunction() {
        trace(_this);  // 출력 : null
        var _this:String = "local";
        trace(_this); // 출력 : local
}
subScopeFunction();
trace(_this);  // 출력 : global

위 코드에서 보이는 것과 같이 AS3에서는 전역 변수와 지역 변수명이 같을 경우에는 지역변수는 지역 스코프 내에서만 유효한 값을 갖게 된다. 이는 ActionScript 3.0의 컴파일러가 컴파일을 시도할 때 스코프 내의 변수들을 먼저 불러오기 때문이다.

subScopeFunction() 스코프 내의 첫 번째 행에서 global영역에서 지정한 변수명과 동일한 변수명을 사용하여 출력을 하였으나 subScopeFunction() 스코프 내에 global 변수명과 동일한 지역변수를 var를 통해서 선언하였기 때문에 최초 subScopeFunction() 함수를 컴파일 할 때 라인 위치와는 상관없이 지역변수 _this의 메모리 영역을 먼저 잡아 놓게 된다. 이 때문에 subScopeFunction() 첫 행의 결과는 null을 출력한다.

AS3에서는 형태 지정이 없는 변수만 디폴트 값이 undefined이고 String이나 Object의 디폴트 값은 null, Boolean 는 false, uint는 0, Number는 NaN 값이 디폴트 값이다.


 

    

설정

트랙백

댓글

[AS3] 변수 형태에 관한 이야기

Programming/ActionScript 3.0 2007. 7. 9. 19:41

AS3의 형태 시스템의 특징은 다음과 같다. 아래의 코드에 대해서 생각해 보면 오브젝트형의 변수 str에 수치 0을 대입하여 공문자열과 비교하고 있다.

var str:* = 0;
if ("" == str) {
        trace("str은 공문자열");
}


위의 If 문은 공문자를 검출하기 위한 것이지만 실제로 이 코드를 실행하면 ”str은 공문자열”이라고 출력된다.

이 결과는 AS3가 약한 형태 성질을 가지고 있기 때문에 일어난다. ActionScript에서는 '+' 등의 오퍼레이터에 의해서 복수의 데이터형이 혼합되면 처리 전에 암묵적으로 형태 변환을 한다. 예를 들면 trace("count:" + 0)와 같이 문자열과 수치를 더하면 0의 값이 문자열로 변환되어 count:0이라는 결과를 얻게 된다. trace 예와 같은 암묵적 형태 변환은 ActionScript 3.0 이전 버전에서도 있었던 것이지만 위에서 처음 예로 든 코드의 경우는 ActionScript 2.0에서는 공문자열과 str은 같지 않은 것으로 나온다.

암묵적 형태 변환은 위의 trace() 예와 같이 비교적 편리한 기능으로서 사용되지만 한편으로는 예기치 못한 결과가 나올 수 있다. 예를 들면 위에 언급한 코드의 경우 실제로 컴파일러가 어떠한 변환을 통해 true 라는 결과가 나오는지 개발자가 직감적으로는 이해 하기가 어려운 점이 있다.

    

설정

트랙백

댓글

[AS3] CustomMath 클래스 테스트 - Angle

Programming/ActionScript 3.0 2007. 7. 9. 06:25
Sprite의 angle 테스트를 해보았다. 라이브러리에 있는 Sprite에 클래스를 등록할 때 동립된 클래스 파일로 존재하지 않고 main 클래스 소스파일 내에 internal class로 정의할 경우에는 라이브러리에 있는 Sprite을 참조하지 못한다. 아무래도 AS3의 namespace 때문이지 않을까 싶다.

전체적으로 확실히 AS3에서 속도가 향상된 듯 싶다. 7*15(105개)의 Sprite을 main 클래스의 Event.ENTER_FRAME  이벤트를 적용하여 움직임을 주었는데 CPU에 그렇게 큰 부담이 없는 듯 싶다.

MouseEvent.MOUSE_DOWN, MouseEvent.MOUSE_UP 이벤트를 적용해 봤는데 MouseDown일 때 움직임이 재미있다. 초등학교 운동회때 엄마를 졸라서 샀던 색깔종이(?!) 같다...



[Flash] http://jasu.tistory.com/attachment/cfile29.uf@25428C395880211C108D39.swf





    

설정

트랙백

댓글

[AS3] custom 이벤트의 기본적인 dispatchEvent 사용

Programming/ActionScript 3.0 2007. 7. 7. 23:05
Event 클래스를 확장하면 자신의 커스텀 이벤트 클래스를 정의할 수 있다. 예를 들면 아래와 같은 경우다.
















package{
import flash.events.Event;
public class CustomEvent extends Event{
public function CustomEvent(){
super("customEvent");
}
public override function clone():Event{
return new CustomEvent();
}
}
}

(Event의 서브 클래스로 상속할 때는 clone() 메소드를 오버라이드할 필요가 있다.)

EventDispatcher 클래스의 dispatchEvent() 메소드를 사용하면 자동으로 이벤트의 dispatch가 생긴다. 예를 들면 Sprite는 EventDispatcher의 서브 클래스이기 때문에 다음과 같이 CustomEvent을 dispatch 할 수 있다.
package{
import flash.display.Sprite;
public class CustomEventSprite extends Sprite{
public function dispatchCustomEvent():void{
dispatchEvent(new CustomEvent());
}
}
}

그리고는 이벤트 처리를 호출하기 위해 이벤트 리스너를 등록하면 된다.
package{
import flash.display.Sprite;
public class EventTest extends Sprite{
public function EventTest(){
var ceSprite:CustomEventSprite = new CustomEventSprite();
ceSprite.addEventListener("customEvent", onCustomEvent);
ceSprite.dispatchCustomEvent();
}
private function onCustomEvent(evt:CustomEvent):void{
trace("dispatch CustomEvent");
}
}
}

하지만 AS3에서는 다중 상속이 허용되지 않기 때문에 모든 클래스를 EventDispatcher의 서브 클래스로 만들 수 있는 것이 아니다. 상속하고 있는 클래스의 경우에는 IEventDispatcher 인터페이스를 사용한다. 클래스 내부에서 EventDispatcher의 인스턴스를 가져와서 처리를 Delegate하는 방법이다.

    

설정

트랙백

댓글

[AS3] Sprite의 마우스 이벤트

Programming/ActionScript 3.0 2007. 7. 6. 10:46
Sprite의 마우스 이벤트

AS3에서 버튼을 작성하는 경우 우선은 SimpleButton의 사용을 생각할 수 있지만 간단하지 않은버튼 형태의 경우는 SimpleButton을 대신하여 Sprite를 사용할 수 있다. 그 경우 버튼으로서 사용하는 Sprite의 안에 다른 Sprite 오브젝트로서 배치하고 버튼 형태의 모션을 만드는 것도 있을 수 있다.
그렇지만 이 때 다음과 같은 문제가 발생할 수 있다. 버튼으로서 사용한 Sprite의 안에 있는  Sprite도 마우스 이벤트의 대상이 되는 것이다. 이로 인해서 버튼용의 Sprite가 아니라 그 안에 있는 Sprite가 이벤트의 타겟이 되어 버릴 수 있다.(AS3는 DisplayObject의 서브 클래스를 추가하면 의도하지 않아도 이벤트 플로우가 바뀌어 버린다.)

이러한 문제를 방지하려면 mouseEnabled 프롭퍼티를 false로 설정하면 가능하다. Sprite 하나하나에 임의로 설정하여 관리하는 것이 귀찮으면 버튼용 Sprite의 mouseChildren 프롭퍼티를 false로 하는 방법도 있다. 이렇게 하면 버튼용 Sprite의 안에 있는 오브젝트는 모두 이벤트 대상에서 제외된다.

public mouseEnabled : Boolean  // 마우스 이벤트를 받을까
public mouseChildren : Boolean // 아이 오브젝트가 마우스 이벤트를 받을까
public buttonMode : Boolean // 버튼으로서 행동할까
public hitArea : Sprite // 마우스 이벤트의 대상이 되는 화면상의 영역
public useHandCursor : Boolean // 커서의 형상을 손의 형태로 할까

buttonMode 프롭퍼티를 true로 설정하면 마우스가 Sprite의 위에 왔을 때 마우스의 모양을 자동적으로 손 모양으로 바꾸어 준다.(useHandCursor 프롭퍼티 쪽이 우선)

    

설정

트랙백

댓글

[AS3] SimpleButton 클래스

Programming/ActionScript 3.0 2007. 7. 6. 10:15

SimpleButtonInteractiveObject의 서브 클래스로서 마우스의 조작에 따라 버튼처럼 행동할 수 있다. Flash authoring tool로 버튼 심볼을 작성하면 4개의 프레임이 생기는데 SimpleButton 에도 각각의 프레임에 대응하는 프롭퍼티가 존재한다.

 
public upState : DisplayObject        //
업 상태의 표시 오브젝트
public overState : DisplayObject      // 오버 상태의 표시 오브젝트
public downState : DisplayObject     // 다운 상태의 표시 오브젝트
public hitTestState : DisplayObject    // 히트 테스트용 오브젝트

 
이상의 4개의 프롭퍼티에 대응하는 마우스 조작 상태로 의도된 표시를 표현한다. DisplayObject 를 설정하는 것이 SimpleButton의 기본적인 사용 방법이다.

var myButton:SimpleButton = new SimpleButton();
addChild(myButton);

// 각 스테이트용의 오브젝트를 작성(하나의 Shape를 공유)
var stateShape:Shape = new Shape();
stateShape.graphics.lineStyle(2, 0x202020);
stateShape.graphics.beginFill(0xFF0000);
stateShape.graphics.drawRect(10, 10, 50, 50);

// 버튼 오브젝트의 프롭퍼티를 설정
myButton.upState = stateShape;
myButton.downState = stateShape;
myButton.overState = stateShape;
myButton.hitTestState = stateShape;

SimpleButton에는 위 4개의 상태 오브젝트 외에 아래와 같은 프롭퍼티가 있다.

 
public trackAsMenu : Boolean       //
메뉴와 같은 사용법을 할 것인가
public enabled : Boolean            // 버튼을 유효하게 할 것인가
public useHandCursor : Boolean     // 커서의 모양을 핸드커서 형태로 것인가

 
trackAsMenu
는 마우스를 눌렀다가 다른 장소에서 마우스를 놓았을 경우에서도 click 이벤트를 받고 싶은 경우에 사용한다. 보통 click 이벤트는 동일 오브젝트상에서 마우스를 클릭하는 행위를 하지 않으면 dispatch 되지 않지만 trackAsMenu true로 해 두면 다른 오브젝트상에서 마우스를 놓아도 적용된다. SimpleButton 오브젝트상에서 마우스를 놓았을 경우에도 그 SimpleButton 오브젝트에 click 이벤트가  dispatch된다. 메뉴를 만들 때 유용하다.

enabled 프롭퍼티는 버튼의 유효/ 무효를 선택할 수 있다. enabled false로 설정하면 실제 마우스를 조작해도 외형상은 반응하지 않는 것 처럼 보이지만 이벤트는 dispatch된다.

useHandCursor 프롭퍼티는 디폴트가 true. 보통은 특별히 신경 쓸 필요는 없을 것 같다.

    

설정

트랙백

댓글

[AS3] argument 오브젝트

Programming/ActionScript 3.0 2007. 7. 6. 08:34
argument 오브젝트

디폴트 값으로 지정되어 있지 않은 인수를 생략 하고 함수를 호출하려고 하면 컴파일러가 에러를 돌려준다. 또 선언되고 있는 것보다 많은 인수를 지정하여 호출하는 경우도 compile error가 되지만  둘 모두 실행은 된다.

인수에 액세스 하기 위해서는 arguments라고 하는 오브젝트를 사용할 수 있다. 이것은 선언 없음으로 함수 내에서 참조할 수 있는 오브젝트로 건네 받은 인수의 배열이라고 부르며 오브젝트 (arguments.callee)를 프롭퍼티로서 가지고 있다. 인수명에 arguments이 사용되고 있는 함수 내에서는 arguments는 그 인수를 가리키게 되어 arguments 오브젝트를 사용할 수 없게 된다.

arguments 오브젝트는 아래와 같은 재귀 함수에서 처럼 편리하게 이용할 수 있다.
var factirial:Function = function(x:int):int {
if (x == 0) {
return 1;
} else {
return (x * arguments.callee(x - 1));
}
}

인수의 수가 결정되지 않은 경우는 compile error를 무시하고 함수를 호출하지 않으면 안 된다는 것은 좋지 않다. 그래서 AS3 에는 arguments를 대신하는 다음과 같은 기능이 준비되어 있다.

「... 」 인수

AS3의 마지막 인수로서 「... + 임의의 이름」을 지정하면 정의된 수 이상의 인수를 건네줄 수 있게 된다. 명시적으로 이름이 지정되어 있지 않은 인수는 「임의의 이름」으로 지정된 이름을 가지는 배열로서 사용할 수 있다. 아래의 예에서는 rest라고 하는 배열에 2 와 3을 전달한다.
function sampFunc(x:int, ... rest) {
if (rest.length > 0) {
trace(rest[0];
}
}
// 2가 출력된다.
sampFunc(1, 2, 3);

arguments 오브젝트와 달리 이 방법으로 하면 컴파일러도 불만이 없다. 함수 정의로부터 인수의 수를 정하지 않았다는 것을 컴파일러는 인지할 수 있게 된다. 사전에 인수의 수를 특정할 수 없는 경우는 「... 」 의 사용을 추천한다. 단,「... 」이 지정되어 있으면 arguments 오브젝트는 사용할 수 없다.

    

설정

트랙백

댓글

[AS3] URLVariables 클래스

Programming/ActionScript 3.0 2007. 7. 6. 06:55
URLVariables 클래스
public 함수 URLVariables(source:String = null)

새로 URLVariables 오브젝트를 작성한다. URLVariables 오브젝트를 URLRequest 오브젝트의 data 프롭퍼티에 건네준다.

스트링과 함께 URLVariables constructor을 호출하면 decode() 메소드가 자동적으로 실행되고 그 스트링이 URLVariables 오브젝트의 프롭퍼티로 변환된다.

파라미터
    source:String (default = null) —URL encode 된 스트링.


decode() 메소드
public function decode(source:String):void

변수 스트링을 지정하면 URLVariables 오브젝트의 프롭퍼티로 변환된다.

이 메소드는 URLVariables 이벤트에 의해서 내부적으로 사용된다. 대부분의 경우 유저가 직접 이 메소드를 호출할 필요는 없다.

다음의 예에서는 http://www.[yourDomain].com/application.jsp로 호스트 되는 리모트 어플리케이션을 열어서 URLVariables 오브젝트로 받는 유저 세션에 관한 데이터를 어플리케이션에 건네준다.

이 예의 내용은 다음과 같다.

   1. constructor함수는 request라는 이름의 리모트 어플리케이션의 URL을 파라미터로 취득하는  URLRequest 인스턴스를 작성한다.
   2. URLVariables 오브젝트를 작성하고 2개의 프롭퍼티에 값을 할당한다.
   3. URLVariables 오브젝트가 URLRequest 오브젝트의 data 프롭퍼티에 할당한다.
   4. navigateToURL를 호출하고 새로운 브라우저 윈도우를 열어서 리모트 어플리케이션의 URL에 접속한다.

메모 : 이 예를 실행하려면 리모트 어플리케이션의 URL을 실제의 URL로 바꿀 필요가 있다. 또한 URLVariables 오브젝트의 Flash Player가 보낸 정보를 처리하기 위한 서버 코드가 필요하다.
package {
import flash.display.Sprite;
import flash.net.navigateToURL;
import flash.net.URLRequest;
import flash.net.URLVariables;

public class URLVariablesExample extends Sprite {

public function URLVariablesExample() {
var url:String = "http://www.[yourDomain].com/application.jsp";
var request:URLRequest = new URLRequest(url);
var variables:URLVariables = new URLVariables();
variables.exampleSessionId = new Date().getTime();
variables.exampleUserLabel = "guest";
request.data = variables;
navigateToURL(request);
}
}}


    

설정

트랙백

댓글

[AS3] URLLoader 클래스

Programming/ActionScript 3.0 2007. 7. 6. 06:32
URLLoader 클래스
외부로부터의 XML 데이터등을 읽어들일 때는 URLLoader 클래스를 사용할 수 있다.


URLRequest 클래스를 통한 데이터 송신
URLLoader를 사용해서 서버에 리퀘스트를 보내려면 우선 URLRequest 클래스의 인스턴스를 만든다. URLRequest의 오브젝트에는 리퀘스트 URL이나 헤더 정보 등을 지정할 수 있다.

아래 작성한 코드는 URLRequest 오브젝트를 인수로서 URLLoader의 load() 메소드를 호출한다.




var myReq:URLRequest = new URLRequest();
myReq.url = "foo.xml"; // constructor의 인수로도 지정 가능
var myLoader:URLLoader = new URLLoader();
myLoader.load(myReq);
HTTP 헤더에 정보를 추가하는 경우는 항목 마다 URLRequestHeader 클래스의 인스턴스를 작성하여 URLRequestHeader 오브젝트의 requestHeaders 속성(Array 형태)에 추가한다.
var myReq:URLRequest = new URLRequest("foo.xml");
var myRH:URLRequestHeader = new URLRequestHeader("pragma", "no-cache");
myReq.requestHeaders.push(myRH);
var myLoader:URLLoader = new URLLoader();
myLoader.load(myReq);

수신한 데이터의 처리
load()를 실행하고 나서 데이터의 읽기 처리가 끝날 때까지는 ActionScript로부터 읽어 들인 데이터에 액세스 할 수 없다. URLLoader는 수신 처리를 완료하면 complete 이벤트를 발생시키므로 complete 이벤트에 대한 이벤트 핸들러 내에서 데이터 조작을 실시해야 한다. 읽어들인 데이터는 URLLoader의 data 속성으로부터 액세스 할 수 있다.
myLoader.addEventListener(Event.COMPLETE, completeHandler);
myLoader.load(new URLRequest("foo.xml"));

private function completeHandler(event:Event):void {
trace(myLoader.data);
}

읽혀진 데이터는 DataFormat 클래스에 정의하고 있는 3종류의 포맷 형태를 갖는다. URLLoader 오브젝트의 dataFormat 속성을 보면 다음과 같다.

    * DataFormat.TEXT : String 형의 문자열
    * DataFormat.BINARY : ByteArray 형의 바이너리 데이터
    * DataFormat.VARIABLES : URL encode 된 폼 변수를 가진다 URLVariables 오브젝트

데이터의 송신
서버에 데이터를 송신할 때도 위와 같이 3종류의 포맷을 사용할 수 있다. 송신하는 데이터를 URLRequest 오브젝트의 data 속성에 세트 하면 리퀘스트시에 세트한 데이터가 보내진다.

아래의 예에서는 URLVariables 오브젝트를 POST 형태로 송신하고 있다. 이 경우 데이터는 x-www-form-urlencoded 포맷에 encode 되어 보내진다.

var myVars:URLVariables = new URLVariables();
myVars.userID = "guest";
myVars.password = "foo";
myReq.data = myVars;
myReq.url = "ww.sample.com/foo.jsp";
myReq.method = URLRequestMethod.POST;
myLoader.load(myReq);

송신 방법 (GET/POST)은 URLRequest 오브젝트의 method 속성에 URLRequestMethod 클래스에 정의된 값을 사용하여 지정한다. 디폴트는 GET다. POST하는 경우는 데이터의 MIME 타입을 URLRequest 오브젝트의 contentType 속성으로 설정할 수 있다. ByteArray 오브젝트를 송신하는 경우는 GET은 사용할 수 없다.

    

설정

트랙백

댓글

[AS3] navigateToURL 함수

Programming/ActionScript 3.0 2007. 7. 6. 06:13
navigateToURL 함수

AS3 어플리케이션으로부터 또 하나의 브라우저 윈도우를 열고 싶을 때, 또는 현재 AS3 어플리케이션을 실행중의 윈도우를 다른 HTML 컨텐츠로 바꾸고 싶을 때, navigateToURL() 함수를 사용한다. AS3이전 버전에서는 getURL()을 사용하였다. 아래는 navigateToURL() 함수의 정의.

public function navigateToURL(request:URLRequest, window:String = null):void

1 첫 번째 인수에는 URLRequest 오브젝트를 지정한다. 이 오브젝트에는 URLLoader 클래스에서는  리퀘스트 하는 URL이나 헤더 정보, 그리고 송신하는 데이터와 송신 방법 등을 지정한다.

2 번째의 인수에는 리퀘스트의 결과를 수신하는 윈도우 target을 지정한다. 이것은 디폴트값이 정의되고 있기 때문에 생략이 가능하다. 생략 했을 경우에는 새로운 윈도우가 열린다. 즉 "_blank" 를 지정한 것과 동등의 결과가 된다.

아래의 샘플에서는 navigateToURL()의 두번째 인수를 "_self"로 하고 있기 때문에 AS3 어플리케이션을 실행하고 있는 윈도우에서 컨텐츠를 열게 된다.
import flash.net.navigateToURL;

var myVars:URLVariables = new URLVariables();
myVars.currentTime = new Date().getTime();
myVars.city = "Tokyo";

var myReq:URLRequest = new URLRequest();
myReq.url = "http://www.sample.com/weather";
myReq.data = myVars;

// 현재의 윈도우에 컨텐츠를 연다.
navigateToURL(myReq, "_self");

navigateToURL() 함수를 사용하려면 import해서 사용한다.


sendToURL() 함수
AS3 어플리케이션으로부터 서버에 데이터를 보내고 싶지만 결과는 무시하고 싶을 때는 sendToURL() 함수를 사용한다. 사용법은 위에서 소개한 것처럼 navigateToURL() 함수와 거의 비슷하다. 차이는 2번째의 인수가 없다는 것이다.

public function sendToURL(request:URLRequest):void


import flash.net.sendToURL;

var myVars:URLVariables = new URLVariables();
myVars.user = "foo";
myVars.data = "hello";

var myReq:URLRequest = new URLRequest();
myReq.url = "http://www.sample.com/post";
myReq.data = myVars;
myReq.method = URLRequestMethod.POST;
// 서버에 데이터를 송신
sendToURL(myReq);


    

설정

트랙백

댓글

[AS3] 클래스 액세스 제한

Programming/ActionScript 3.0 2007. 7. 6. 00:52
프롭퍼티의 선언에 private로 지정하면 다른 클래스에서는 참조할 수 없게 된다. 또 public으로 지정했을 경우는 어떤 클래스에서도 참조할 수 있다.

Protected로 지정한 프롭퍼티는 계승한 클래스에서는 참조를 할 수 있다. Default인 internal 의 경우는 같은 패키지내의 클래스이면 참조가 가능하다.

주의할 것은 protected의 경우 다른 패키지의 클래스에서 참조를 시도해도 서브 클래스이면 참조가 가능하다는 것이다. 반대로 protected의 프롭퍼티는 같은 패키지내의 클래스에서도 서브 클래스가 아니면 참조할 수 없다는 것이다.

또 internal의 프롭퍼티는 같은 패키지내의 서브 클래스에서만 참조가 가능하다.

예를 들어보면 우선 foo라는 패키지에 FooBase 클래스를 정의한다. 클래스 내에는 protected와 internal 의 2종류의 함수를 정의한다.
package foo
{
public class FooBase
{
protected function protectedFunc():void {
}
internal function internalFunc():void {
}
}
}
다음은 bar라고 하는 패키지에 상기 FooBase의 서브 클래스를 정의한다. 함수를 오버라이드(override) 하기 위해 override 키워드를 사용하고 있다.
package bar
{
import foo.FooBase;

public class BarSub extends FooBase
{
// 부모클래스의 정의를 오버라이드(override)
override protected function protectedFunc():void {
}
// 여기는 internal이기 때문에 오버라이드(override) 할 수 없다.
override internal function internalFunc():void {
}
}
}
위 코드를 컴파일 해 보면 protectedFunc() 메소드는 가능하지만 internalFunc() 메소드는 그런 함수는 발견되지 못하여 에러를 출력한다.

또 서브 클래스내의 코드에서 직접 부모클래스의 protected 프롭퍼티를 참조할 수 없다.
public class BarSub extends FooBase
{
public function callProtected():void {
var foo:FooBase = new FooBase();
// protected 의 메소드를 호출해 본다
foo.protectedFunc();
}
}
위의 예의 경우 callProtected()에서 에러가 발생한다.

    

설정

트랙백

댓글

[AS3] ActionScript 3.0 strict 옵션의 기능

Programming/ActionScript 3.0 2007. 7. 5. 17:22
서브 클래스를 정의하려면 extends 키워드를 사용한다.
// 부모클래스 정의
public class MyBase
{
public function hello():String {
return "hello";
}
}

// 서브 클래스의 정의
public class MySub extends MyBase
{
}


서브 클래스의 오브젝트는 부모클래스의 오브젝트와 같게 사용할 수 있다.
// MyBase 형의 변수에 대입
var base:MyBase = new MyBase();
var sub:MyBase = new MySub();

// MyBase 형의 인수를 받는 함수에 건넨다
needBase(sub);
needBase(base);

public function needBase(obj:MyBase):void {
trace(obj.hello());
}
반대로 부모클래스를 서브 클래스로 대신하여 인수로 전달 할 수 없다, 아래의 코드는 ActionScript 3.0 환경 설정에서 -strict 옵션을 붙이지 않으면 실행할 수 있지만 ActionScript 2.0에서는 에러를 출력한다.
var sub:MyBase = new MySub();
needSub(sub);

public function needSub(obj:MySub):void {
trace(obj.hello());
}

    

설정

트랙백

댓글

[AS3] 이벤트 리스너와 garbage collection

Programming/ActionScript 3.0 2007. 7. 5. 04:35
필요 없는 오브젝트의 참조가 남아있으면 그 오브젝트가 사용하고 있는 메모리 영역을 사용할 수 없게 된다. 특히 복수가 참조하는 오브젝트에 대해서는 참조를 해제하는 것을 잊어버리게 되면 메모리의 낭비가 발생하므로 주의해야 한다.

이벤트 리스너를 등록하려면 이벤트의 타겟으로 되는 오브젝트와 이벤트 리스너를 가지는 오브젝트 사이에 참조를 할 수 있다. AS3에서는 아래와 같이 기술한다.

eventTarget.addEventLisener("eventType", eventHandler);

이 코드를 실행하면 eventTarget과 현재 스크립트가 포함된 this 사이에 참조가 만들어진다. 하지만 이것은 명시적인 참조의 추가가 아니기 때문에 참조의 삭제가 필요한 경우 간과할 수 있다.

아래는 이벤트 리스너 추가시에 참조의 취급 방법에 대한 내용이다.


참조의 방향
참조에는 방향성이 있다. 즉, 오브젝트간의 참조는 한 방향으로만 가능하다. 예를 들면 아래와 같은 코드가 있을 때,
var foo = new Foo();
foo.bar = this;
foo = null;
1행에서 만들어진 참조는 this -> new Foo() 방향으로 만들어진 참조이다. 2행에서 만들어진 참조는 1행과 반대로 new Foo() -> this 방향으로 만들어 진 참조다. 3행에서 1행의 참조를 삭제하게 되면 this -> new Foo()으로의 참조를 할 수 없다.

가비지컬렉터는 오브젝트 트리의 루트로부터 참조를 찾아 들어 간다. 우선 루트의 오브젝트를 찾아내고 다음에 그 오브젝트의 오브젝트를 찾아내는 동작을 반복하게 된다. 위 샘플을 실행했을 경우 this에 new Foo()로 만들어진 오브젝트를 찾아 낼 수 없다. 즉 2행째에 작성한 참조가 남아있다고 해도 3행을 실행하게 되면 메모리 문제는 해결될 수 있다.


오브젝트에 이벤트 리스너 추가
오브젝트에 이벤트 리스너를 추가할 경우에 참조 방향으로는 아래와 같다.
import flash.events.Event;
import flash.events.MouseEvent;
var foo = New Foo();
addChild(foo);
foo.addEventListener(MouseEvent.CLICK, clickHandler);

function clickHandler(evt:Event):void{
trace(this);
}
위 코드에서 foo 오브젝트를 작성하고 그 오브젝트에 clickHandler라는 이벤트 리스너를 등록하였다. clickHandler 메소드는 스크립트가 작성된 this 오브젝트의 메소드가 된다.

이러한 경우 foo 오브젝트의 참조를 삭제할 때 이벤트 리스너도 삭제하지 않으면 메모리에 잔존하는 문제의 원인이 될 수 있다. 아래와 같이 오브젝트로부터 this에 이벤트 리스너를 설정할 경우도 같다.
parent.addEventListener("click", clickHandler);
약한 참조의 이용
약한 참조는 참조가 존재하고 있어도 가비지콜렉터에 의해서 참조로서 보이지 않는 참조이다. 이는 매우 편리하게 사용할 수 있는데 이벤트 리스너에 의해 생성되는 참조가 모두 약한 참조라면 참조의 방향을 신경 쓰지 않고 등록한 리스너를 방치해 두어도 문제가 되지 않기 때문이다. 이벤트 리스너를 등록할 때 약한 참조를 사용할지를 지정할 수 있다. addEventListener()의 5번째 인수를 true로 적용하면 약한 참조를 사용할 수 있다.
addEventListener("eventType", listenerHandler, false, 0, true);
3번째와 4번째 인수는 false와 0 값을 지정해 두면 대체적으로 문제가 없기 때문에 위와 같은 형태로 5번째 인수를 false와 true로 적용하여 강한 참조와 약한 참조를 사용할 수 있다.

    

설정

트랙백

댓글

[AS3] Flash Player9의 새로운 풀 스크린 모드

Programming/ActionScript 3.0 2007. 7. 4. 23:31
Flash Player9 업데이트 3에서는 공개되는 하드웨어 기능을 이용한 풀 스크린 모드가 추가되었다.

하드웨어 스켈링의 사용법
Flash Player9 업데이트 3의 Stage 오브젝트에는 fullScreenSourceRect라고 하는 속성이 추가된다. 이 속성은 AS2와 AS3에서 모두 사용 가능하다. fullScreenSourceRect에 의해 지정된 영역은 하드웨어의 스켈링 기능에 의해 표현 되기 때문에 기존의 풀 스크린 모드보다 퍼포먼스와 화질 면에서 현격히 개선되고 있다.

아래 샘플은 Stage를 화면 전체에 넓히는 기능이다.




import flash.geom.*;
function goFullScreen()
{
Stage["fullScreenSourceRect"] = new Rectangle(0, 0, Stage.width, Stage.height);
Stage["displayState"] = "fullScreen";
}

비디오를 풀 스크린으로 표시하는 경우는 Rectangle 크기를 비디오의 오리지날의 크기로 한다.

AS3에서 Stage의 fullScreenSourceRect속성을 적용하려면 playerglobal.swc를 클래스패스영역에 포함 시켜야 한다. CS3 의 ActionScript 3.0/classes 폴더에 기존에 파일을 아래 파일로 바꿔주어야 한다. (playerglobal.swc파일을 첨부한다.)



비디오의 퀄리티와 용량에 따라 다르겠지만 대체적으로 fullScreenSourceRect속성을 사용하면 비디오를 풀스크린으로 표현했을 때의 CPU 점유율은 사용하지 않은 것 보다 대략 절반 정도로 떨어지고 화질 면에서도 개선된 점을 발견할 수 있다.

    

설정

트랙백

댓글

[AS3] AS3와 AS2의 통신 LocalConnection 클래스

Programming/ActionScript 3.0 2007. 7. 4. 04:59

AS3로 만든 플래시에서 AS2로 만든 swf를 로드 할 수는 있지만 그 안에 있는 메소드나 변수에 접근 할 수는 없다. 블로그의 메뉴와 배경에 나타나는 나비는 as2로 만들었고,  infinite메뉴는 따로 AS3로 만들었기 때문에 서로 다른 swf 파일로 되어 있다.

고민이 되었던 부분은 infinite 메뉴를 클릭했을 때 fullscreen 형태로 컨텐츠를 보여주게 되면서 아래에 있는 블로그의 기존에 생성하던 나비와 플레이 되고 있던 음악은 종료해야 한다는 것이었다. 나비의 경우는 화면에 보이지 않으면서 불필요하게 CPU를 낭비하게 되고 음악 또한 불필요하다.

그래서 직접 AS3 코드에서 AS2코드를 참조할 수 없으니 간접적으로 참조할 수 있는 방법으로 LocalConnection 클래스를 사용하게 되었다. LocalConnection의 경우는 as2,와 as3에서 서로 호환적으로 사용이 가능하다.

    

설정

트랙백

댓글

[AS3] root 변수 참조 방법

Programming/ActionScript 3.0 2007. 7. 4. 04:42
root에 있는 변수나 메소드에 접근할 때 actionscript 2.0에서는 _root를 절대적 참조 영역으로 사용하였으나 as3부터는 _root를 통해 직접적으로 변수나 함수를 참조할 수가 없다.

as3에서 root영역에 있는 변수나 함수를 참조하기 위해서는 아래와 같은 형태로 가능하다. (코드의 일부 개념적인 부분은 한상훈님의 설명을 참조하였다.)  'ADDED_TO_STAGE'라는 이벤트는 constructor를 통해서 인스턴스를 생성할 때 메모리 영역을 할당 받기 전의 참조로 인한 문제를 방지하기 위해 사용한 듯한데 아직까지 as3의 개념이 확실히 잡히지 않았다.






import flash.events.MouseEvent;
import flash.events.Event;

var menu_num:Number = 100;

mc.buttonMode = true;
mc.addEventListener(MouseEvent.CLICK, clickHandler);

function clickHandler(evt:Event):void{
var rootTest:RootTest = new RootTest();
addChild(rootTest);
rootTest.getTrace();
}

package{
import flash.display.MovieClip;
import flash.events.Event;

public class RootTest extends MovieClip{

private var _root:MovieClip;

public function RootTest(){
addEventListener(Event.ADDED_TO_STAGE, initialize);
}
private function initialize(evt:Event):void{
removeEventListener(Event.ADDED_TO_STAGE, initialize);
_root = root as MovieClip;//or MovieClip(root);
}
public function getTrace():void{
trace(stage);
trace(_root.menu_num);
}
}}
출력 :
[object Stage]
100

    

설정

트랙백

댓글